Bỏ qua

Sinh tạo Đa phương thức (Cross-Modal Generation)

Sinh tạo đa phương thức sinh ra đầu ra ở một phương thức này có điều kiện bởi đầu vào từ phương thức khác; văn bản sang ảnh, ảnh sang văn bản, văn bản sang âm thanh, và hơn thế nữa. Tài liệu này bao quát DALL-E, Stable Diffusion, classifier-free guidance, ControlNet, mô tả ảnh (image captioning), văn bản sang video (Sora), và sinh tạo văn bản sang âm thanh.

  • Ở các file 01-03 của chương này, bạn đã học cách biểu diễn, căn chỉnh, và token hóa các phương thức khác nhau. Giờ đến phần sáng tạo: sinh ra một phương thức từ một phương thức khác. Sinh tạo đa phương thức chính là động cơ đứng sau các công cụ văn bản-sang-ảnh, các hệ thống tổng hợp video, các mô hình sáng tác nhạc, và mô tả ảnh. Hãy hình dung nó như việc dạy một cỗ máy trở thành một nghệ sĩ đa phương thức — bạn mô tả bằng lời những gì mình muốn, và nó vẽ, hoạt họa, hoặc sáng tác.

  • Ý tưởng cốt lõi là sinh tạo có điều kiện (conditional generation): cho một đầu vào từ phương thức \(A\) (ví dụ: văn bản), sinh ra đầu ra ở phương thức \(B\) (ví dụ: ảnh). Một cách hình thức, ta học một mô hình \(p_\theta(y \mid x)\) với \(x\) là tín hiệu điều kiện và \(y\) là đầu ra được sinh ra. Thách thức là phân bố có điều kiện này cực kỳ phức tạp và có số chiều rất cao — một ảnh 512x512 sống trong không gian \(\mathbb{R}^{786432}\), và có rất nhiều ảnh hợp lệ cho một câu lệnh văn bản duy nhất.

Tổng quan sinh tạo đa phương thức: các phương thức văn bản, ảnh, âm thanh, và video được nối bởi các mũi tên chỉ hướng thể hiện các lộ trình sinh như văn bản-sang-ảnh, ảnh-sang-văn bản, văn bản-sang-âm thanh và văn bản-sang-video

Sinh tạo Văn bản-sang-Ảnh (Text-to-Image)

  • Hãy tưởng tượng bạn mô tả một cảnh cho một họa sĩ phác thảo tại tòa án. Người họa sĩ phải diễn giải lời bạn nói, nhớ lại các vật thể trông như thế nào, sắp xếp chúng trong không gian, và vẽ nên bức tranh cuối cùng. Các mô hình văn bản-sang-ảnh làm chính xác điều đó, nhưng chúng phải học tất cả những kỹ năng này từ dữ liệu thay vì từ nhiều năm theo học trường mỹ thuật.

DALL-E: Sinh tạo Ảnh Tự hồi quy (Autoregressive)

  • DALL-E (Ramesh và cộng sự, 2021) coi việc sinh ảnh như một bài toán dự đoán chuỗi — cùng mô hình với các mô hình ngôn ngữ (Chương 07). Nhìn nhận then chốt là: nếu bạn có thể biểu diễn ảnh dưới dạng các token rời rạc (nhắc lại VQ-VAE từ file 03), thì sinh một bức ảnh đơn giản chỉ là sinh ra một chuỗi token, nối tiếp nhau.

  • Quy trình gồm hai giai đoạn. Đầu tiên, một VAE rời rạc (dVAE) nén một ảnh 256x256 thành một lưới 32x32 các token rời rạc từ một bộ mã (codebook) gồm 8192 mục, giảm ảnh về một chuỗi 1024 token. Thứ hai, một bộ giải mã transformer được huấn luyện để mô hình hóa phân bố kết hợp của 256 token văn bản (mã hóa BPE) nối tiếp với 1024 token ảnh, tổng cộng 1280 token:

\[p(x_{\text{text}}, x_{\text{img}}) = \prod_{i=1}^{1280} p(x_i \mid x_1, \ldots, x_{i-1})\]
  • Khi sinh, bạn đưa vào các token văn bản và mô hình lấy mẫu các token ảnh một cách tự hồi quy, từng cái một. Cách này thanh lịch vì nó tái sử dụng nguyên bộ máy của mô hình ngôn ngữ — cơ chế chú ý, mặt nạ nhân quả (causal masking), lấy mẫu top-k — cho việc tổng hợp ảnh.

  • Nhược điểm là sinh tự hồi quy vốn mang tính tuần tự: sinh 1024 token từng cái một rất chậm, và bất kỳ lỗi nào ở đầu chuỗi sẽ lan rộng. DALL-E đã giảm thiểu điều này bằng cách sinh nhiều ảnh ứng viên rồi xếp hạng lại chúng bằng CLIP (từ file 01) để tìm ảnh khớp nhất với câu lệnh văn bản.

Quy trình DALL-E: các token văn bản và token ảnh được nối thành một chuỗi duy nhất, được xử lý bởi bộ giải mã transformer dự đoán các token ảnh theo kiểu tự hồi quy có điều kiện bởi các token văn bản

Stable Diffusion: Khuếch tán Tiềm ẩn có Điều kiện Văn bản (Latent Diffusion)

  • Stable Diffusion (Rombach và cộng sự, 2022) dùng một cách tiếp cận khác căn bản. Thay vì dự đoán từng token một, nó bắt đầu từ nhiễu thuần túy và dần dần khử nhiễu thành một bức ảnh, có hướng dẫn bởi một câu lệnh văn bản. Nhắc lại các mô hình khuếch tán từ Chương 8 — Stable Diffusion hoạt động trong một không gian tiềm ẩn được nén thay vì không gian điểm ảnh (pixel space), giúp nó hiệu quả hơn rất nhiều.

  • Kiến trúc có ba thành phần phối hợp với nhau. Một bộ mã hóa VAE nén ảnh từ không gian điểm ảnh (\(512 \times 512 \times 3\)) sang một biểu diễn tiềm ẩn (\(64 \times 64 \times 4\)), giảm số chiều đi hệ số 48. Một bộ mã hóa văn bản (thường là CLIP hoặc OpenCLIP) chuyển câu lệnh văn bản thành một chuỗi các vector embedding. Một bộ khử nhiễu U-Net nhận vào latent nhiễu, bước thời gian (timestep), và các embedding văn bản, rồi dự đoán lượng nhiễu cần trừ tại mỗi bước. Điều kiện văn bản đi vào U-Net qua các lớp cơ chế chú ý chéo (cross-attention):

\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V\]
  • trong đó \(Q\) đến từ các đặc trưng ảnh nhiễu, và \(K, V\) đến từ các embedding văn bản. Điều này cho phép mô hình chú ý đến các từ liên quan tại mỗi vị trí không gian — khi khử nhiễu vùng mà một "quả bóng đỏ" nên xuất hiện, mô hình chú ý đến các token "đỏ" và "bóng".

  • Khi suy luận, bạn lấy mẫu \(z_T \sim \mathcal{N}(0, I)\) trong không gian tiềm ẩn, khử nhiễu lặp lại bằng U-Net qua \(T\) bước (thường là 20-50 với lịch trình DDIM), và giải mã latent sạch \(z_0\) trở lại không gian điểm ảnh bằng bộ giải mã VAE. Toàn bộ quá trình tính toán phía trước sinh ra một ảnh 512x512 trong vài giây trên một GPU phổ thông.

Kiến trúc Stable Diffusion: lời nhắc văn bản được mã hóa bởi CLIP, nhiễu ngẫu nhiên trong không gian tiềm ẩn được khử nhiễu dần dần bởi U-Net có cơ chế chú ý chéo đến embedding văn bản, sau đó được giải mã bởi VAE để tạo ảnh cuối cùng

Classifier-Free Guidance trong Thực tế

  • Classifier-free guidance (CFG) là thành phần bí mật giúp các mô hình văn bản-sang-ảnh tạo ra những bức ảnh thực sự khớp với câu lệnh của chúng. Nhắc lại từ Chương 8 rằng CFG huấn luyện mô hình cả có điều kiện và không điều kiện, sau đó khuếch đại tín hiệu có điều kiện tại thời điểm lấy mẫu:
\[\hat{\epsilon} = \epsilon_\theta(x_t, \varnothing) + s \cdot (\epsilon_\theta(x_t, c) - \epsilon_\theta(x_t, \varnothing))\]
  • trong đó \(s\) là thang hướng dẫn (guidance scale). Hãy coi cụm \((\epsilon_\theta(x_t, c) - \epsilon_\theta(x_t, \varnothing))\) như "hướng về phía câu lệnh" — nó nắm bắt điều gì làm cho một dự đoán có điều kiện khác biệt so với một dự đoán không điều kiện. Nhân với \(s > 1\) phóng đại hướng này, đẩy bức ảnh lại gần mô tả văn bản hơn nhưng phải đánh đổi bằng độ đa dạng.

  • Trong thực tế, \(s = 7.5\) là giá trị mặc định phổ biến cho Stable Diffusion. Ở \(s = 1.0\) bạn nhận được đầu ra thô của mô hình (đa dạng nhưng khớp lỏng lẻo với câu lệnh). Ở \(s = 20+\) các bức ảnh trở nên bão hòa quá mức và lặp lại nhưng lại rất sát với văn bản. Giá trị \(s\) tối ưu tùy thuộc vào ứng dụng: khám phá sáng tạo ưu tiên hướng dẫn thấp, trong khi tuân thủ câu lệnh chính xác đòi hỏi hướng dẫn cao.

Imagen: Khuếch tán theo Tầng (Cascaded) với Hiểu biết Ngôn ngữ

  • Imagen (Saharia và cộng sự, 2022) cho thấy một bộ mã hóa văn bản mạnh quan trọng hơn một mô hình ảnh lớn. Thay vì CLIP, Imagen dùng một mô hình ngôn ngữ T5-XXL (từ Chương 07) đã được đóng băng (frozen) làm bộ mã hóa văn bản, vốn có sự hiểu biết phong phú hơn nhiều về ngữ nghĩa ngôn ngữ, tính thành phần (compositionality), và các quan hệ không gian ("một khối lập phương xanh nằm trên một hình cầu đỏ").

  • Imagen dùng cách tiếp cận khuếch tán theo tầng (cascaded diffusion): một mô hình khuếch tán nền sinh ra ảnh 64x64, một mô hình siêu phân giải (super-resolution) thứ nhất phóng to lên 256x256, và một mô hình siêu phân giải thứ hai đạt tới 1024x1024. Mỗi giai đoạn là một mô hình khuếch tán riêng biệt có điều kiện bởi văn bản và (đối với các mô hình phóng to) bởi ảnh độ phân giải thấp hơn. Tầng (cascade) này tránh phải mô hình hóa các chi tiết tinh vi ở độ phân giải nền, cho phép mô hình nền tập trung vào bố cục và ngữ nghĩa trong khi các mô hình phóng to lo phần kết cấu và độ sắc nét.

  • Imagen cũng giới thiệu ngưỡng động (dynamic thresholding): tại mỗi bước khử nhiễu, các giá trị điểm ảnh dự đoán được cắt về một dải dựa trên phân vị (percentile) thay vì một dải cố định \([-1, 1]\). Điều này ngăn chặn các artefact bão hòa ở các thang hướng dẫn cao, một vấn đề phổ biến trong các mô hình khuếch tán.

Parti: Tự hồi quy ở Quy mô Lớn

  • Parti (Pathways Autoregressive Text-to-Image, Yu và cộng sự, 2022) hồi sinh cách tiếp cận tự hồi quy với quy mô khổng lồ. Giống DALL-E, nó chuyển ảnh thành các token rời rạc (dùng ViT-VQGAN) và sinh chúng tuần tự bằng một transformer. Nhưng Parti dùng một transformer encoder-decoder 20 tỷ tham số (dựa trên kiến trúc Pathways) và cho thấy các mô hình tự hồi quy có thể đạt chất lượng ngang khuếch tán khi được mở rộng đủ lớn.

  • Kiến trúc encoder-decoder của Parti là khác biệt then chốt so với thiết kế decoder-only của DALL-E. Văn bản đi qua bộ mã hóa; bộ giải mã thực hiện cơ chế chú ý chéo (cross-attend) đến văn bản đã mã hóa trong khi sinh các token ảnh. Điều này phản chiếu dịch máy (Chương 07) — bạn dịch từ "ngôn ngữ văn bản" sang "ngôn ngữ ảnh".

DiT và Sinh tạo dựa trên Flow

  • Diffusion Transformer (DiT) (Peebles và Xie, 2023) thay thế backbone U-Net trong các mô hình khuếch tán bằng một transformer thuần túy. Mỗi patch tiềm ẩn nhiễu được coi như một token (tương tự như ViT từ Chương 8), và transformer xử lý các token này bằng cơ chế tự chú ý (self-attention) và chú ý chéo đến điều kiện văn bản. DiT cho thấy các transformer có thể mở rộng dự đoán hơn U-Net cho khuếch tán — tăng gấp đôi lượng tính toán một cách đáng tin cậy sẽ giảm một nửa điểm FID.

  • Flow matching (nhắc lại từ Chương 8) đã nổi lên như một lựa chọn thay thế cho mô hình dự đoán nhiễu của khuếch tán. Thay vì dự đoán nhiễu \(\epsilon\) cần trừ, mô hình dự đoán một vận tốc \(v_\theta(x_t, t)\) vận chuyển các mẫu dọc theo các đường thẳng từ nhiễu đến dữ liệu. Stable Diffusion 3Flux áp dụng flow matching với một kiến trúc DiT đa phương thức (MM-DiT), trong đó các token văn bản và ảnh được xử lý chung bởi các khối transformer có cơ chế chú ý hai chiều — cả hai phương thức cùng chú ý lẫn nhau thay vì chỉ văn bản điều kiện hóa các đặc trưng ảnh qua chú ý chéo.

Kiến trúc DiT: các patch tiềm ẩn nhiễu được token hóa như ViT, được xử lý bởi các khối transformer với chuẩn hóa lớp thích ứng cho bước thời gian và điều kiện lớp, sau đó được giải mã trở lại không gian tiềm ẩn

Sinh tạo Văn bản-sang-Video

  • Văn bản-sang-video là văn bản-sang-ảnh với một ràng buộc khắc nghiệt bổ sung: tính liên kết theo thời gian (temporal coherence). Mọi khung hình phải nhất quán bên trong nó (một bức ảnh hợp lệ), nhưng các khung hình liên tiếp cũng phải được nối liền mạch — các vật thể nên di chuyển tự nhiên, ánh sáng nên thay đổi liên tục, và "máy quay" nên đi theo các quỹ đạo vật lý hợp lý. Hãy hình dung sự khác biệt giữa vẽ một bức phong cảnh đơn lẻ và đạo diễn một bộ phim.

Các Thách thức theo Thời gian

  • Video đặt ra ba thách thức vượt ra ngoài việc sinh ảnh. Tính nhất quán theo thời gian (temporal consistency) đòi hỏi các vật thể phải giữ nguyên danh tính xuyên suốt các khung hình — một chú chó ở khung hình 1 phải vẫn là chú chó đó ở khung hình 100. Mô hình hóa chuyển động (motion modelling) đòi hỏi học các động lực học vật lý: vật thể di chuyển thế nào, trọng lực hoạt động ra sao, chất lưu chảy như thế nào. Chi phí tính toán rất lớn: một video 10 giây ở 24 fps và độ phân giải 512x512 chứa \(10 \times 24 \times 512 \times 512 \times 3 \approx 188\) triệu giá trị, gấp khoảng 240 lần dữ liệu của một ảnh đơn lẻ.

Make-A-Video và các Cách tiếp cận Extend-to-Video

  • Make-A-Video (Singer và cộng sự, 2022) dùng một cách tiếp cận thực dụng: bắt đầu từ một mô hình văn bản-sang-ảnh đã huấn luyện trước và thêm các lớp thời gian vào. Nhìn nhận then chốt là bạn đã có các mô hình văn bản-ảnh mạnh được huấn luyện trên hàng tỉ cặp ảnh-văn bản, và bạn chỉ cần học chuyển động từ dữ liệu video (không có nhãn).

  • Make-A-Video chèn các lớp cơ chế chú ý thời gian (temporal attention)tích chập thời gian (temporal convolution) vào một U-Net không gian đã huấn luyện trước. Các lớp không gian (huấn luyện trước trên ảnh) lo phần ngoại hình, trong khi các lớp thời gian mới (huấn luyện trên video) lo phần chuyển động. Cơ chế tự chú ý không gian hoạt động trong từng khung hình; cơ chế chú ý thời gian hoạt động xuyên các khung hình tại mỗi vị trí không gian. Sự phân tích này hiệu quả vì các mẫu thời gian và không gian phần lớn có thể tách rời.

  • Quy trình sinh phản chiếu tầng (cascade) của Imagen: một mô hình nền sinh 16 khung hình ở 64x64, sau đó các mô hình siêu phân giải không gian và thời gian phóng to lên độ phân giải và tốc độ khung hình cuối cùng. Một mạng nội suy khung hình (frame interpolation) tăng độ mượt theo thời gian.

VideoPoet và các Mô hình Video dựa trên Token

  • VideoPoet (Kondratyuk và cộng sự, 2024) thống nhất việc sinh video dưới mô hình ngôn ngữ. Mọi phương thức — văn bản, ảnh, video, âm thanh — đều được token hóa thành các chuỗi rời rạc, và một mô hình ngôn ngữ lớn (LLM) duy nhất được huấn luyện để dự đoán các token một cách tự hồi quy xuyên suốt tất cả các phương thức. Điều này cho phép các khả năng zero-shot: văn bản-sang-video, ảnh-sang-video, video-sang-âm thanh, chỉnh sửa video, và inpainting đều xuất hiện từ cùng một mô hình.

  • VideoPoet token hóa video bằng một bộ mã hóa MAGVIT-v2 (một VQ-VAE 3D, từ file 03) nén chung cả chiều không gian và thời gian. Âm thanh được token hóa bằng SoundStream. Backbone LLM được huấn luyện trước trên văn bản và tinh chỉnh trên các chuỗi token đa phương thức, học phân bố kết hợp xuyên các phương thức.

Khuếch tán Thời gian kiểu Sora

  • Sora (OpenAI, 2024) đã đưa khuếch tán thời gian vào sự chú ý của công chúng nhờ khả năng sinh ra các video dài, liên kết, và vật lý hợp lý. Dù các chi tiết kiến trúc đầy đủ chưa được công bố, các ý tưởng then chốt liên quan đến việc mở rộng DiT ra không-thời-gian (spacetime): các khung hình video được phân rã thành các patch không-thời-gian (spacetime patches) (các khối 3D trải dài trên chiều cao, rộng, và thời gian), được coi như các token cho một transformer lớn.

  • Cách tiếp cận patch không-thời-gian có nghĩa là mô hình xử lý video như một tín hiệu 3D nguyên bản thay vì một chuỗi các khung hình 2D. Điều này cho phép nó nắm bắt các phụ thuộc thời gian dài hạn — mô hình có thể "lên kế hoạch trước" xuyên suốt toàn bộ thời lượng video thay vì sinh từng khung hình một.

  • Sora có thể xử lý các thời lượng, độ phân giải, và tỉ lệ khung hình (aspect ratio) thay đổi bằng cách điều chỉnh số lượng patch không-thời-gian. Huấn luyện trên dữ liệu ở độ phân giải nguyên bản của nó (thay vì cắt mọi thứ về hình vuông) cải thiện chất lượng bố cục và khung hình.

Wan: Sinh Video Mã nguồn Mở

  • Wan (Wan và cộng sự, 2025) là một họ các mô hình sinh video mã nguồn mở (1.3B và 14B tham số) được xây dựng trên backbone DiT với nén thời gian bởi VAE 3D. Wan dùng flow matching thay vì khuếch tán kiểu DDPM truyền thống, học các đường vận chuyển thẳng từ nhiễu đến các latent video. VAE 3D nén video theo cả không gian và thời gian (nén 4x theo thời gian), và DiT xử lý các token tiềm ẩn không-thời-gian kết quả bằng cơ chế chú ý 3D đầy đủ.

  • Wan hỗ trợ văn bản-sang-video, ảnh-sang-video (làm hoạt ảnh một ảnh tĩnh), và chỉnh sửa video. Mô hình 14B sinh ra các video liên kết lên tới 5 giây ở độ phân giải 720p, chứng minh rằng các mô hình mã nguồn mở có thể tiếp cận chất lượng của các hệ thống độc quyền khi các lựa chọn kiến trúc và quy trình huấn luyện được thực hiện cẩn thận.

Quy trình văn bản-sang-video: văn bản được mã hóa bởi mô hình ngôn ngữ, nhiễu không-thời-gian được khử nhiễu bởi transformer khuếch tán thời gian có chú ý đến embedding văn bản, được giải mã bởi VAE 3D thành các khung hình video

Sinh tạo Văn bản-sang-Âm thanh

  • Hãy hình dung một nhạc sĩ sáng tác phim đang đọc một kịch bản và phổ nhạc cho soundtrack. Các mô hình văn bản-sang-âm thanh làm điều gì đó tương tự: cho một mô tả văn bản ("một cơn giông bão với mưa lớn và tiếng sấm ở xa"), chúng sinh ra dạng sóng âm thanh tương ứng. Thách thức là thu hẹp khoảng cách giữa bản chất rời rạc, ký hiệu của văn bản và bản chất liên tục, theo thời gian của âm thanh.

AudioLM: Mô hình ngôn ngữ cho Âm thanh

  • AudioLM (Borsos và cộng sự, 2023) sinh âm thanh bằng cách dự đoán các token âm thanh rời rạc một cách tự hồi quy, vay mượn cùng mô hình ngôn ngữ mà DALL-E dùng cho ảnh. Nó dùng một cấu trúc token phân cấp: các token ngữ nghĩa (semantic tokens) (từ một mô hình tự giám sát như w2v-BERT, nhắc lại Chương 9) nắm bắt nội dung cao cấp (cái gì đang được nói hoặc chơi), trong khi các token âm học (acoustic tokens) (từ SoundStream, một codec âm thanh nơ-ron) nắm bắt các chi tiết âm học tinh vi (nó nghe như thế nào — âm sắc, chất lượng ghi âm).

  • Việc sinh diễn ra trong hai giai đoạn. Đầu tiên, một transformer dự đoán các token ngữ nghĩa dựa trên một prompt âm thanh tùy chọn, thiết lập kế hoạch nội dung cao cấp. Thứ hai, một transformer khác dự đoán các token âm học có điều kiện bởi các token ngữ nghĩa, điền vào các chi tiết âm học. Cấu trúc phân cấp này phản chiếu quy trình chuyển văn bản thành giọng nói (Chương 9) — các token ngữ nghĩa đóng vai trò như các âm vị (phonemes), và các token âm học đóng vai trò như các khung mel spectrogram.

  • AudioLM có thể sinh phần tiếp nối lời nói (cho 3 giây lời nói, sinh 10 giây tiếp theo), phần tiếp nối nhạc, và hiệu ứng âm thanh, tất cả từ một mô hình duy nhất được huấn luyện trên dữ liệu chỉ gồm âm thanh (không cần nhãn văn bản cho tiền huấn luyện).

MusicLM: Âm nhạc có Điều kiện Văn bản

  • MusicLM (Agostinelli và cộng sự, 2023) mở rộng AudioLM sang sinh nhạc có điều kiện văn bản. Nó thêm một embedding kết hợp văn bản-âm thanh (từ MuLan, một mô hình giống CLIP được huấn luyện trên các cặp nhạc-văn bản) để điều kiện hóa việc sinh. Embedding MuLan nắm bắt ý nghĩa ngữ nghĩa của mô tả văn bản ("jazz sôi động với phần độc tấu saxophone") và hướng dẫn việc sinh token phân cấp.

  • MusicLM sinh nhạc ở 24 kHz với các thời lượng tùy ý, duy trì sự liên kết về giai điệu và nhịp điệu qua các bản nhạc dài nhiều phút. Nó cũng có thể điều kiện hóa dựa trên một giai điệu được huýt sáo (dùng các token giai điệu trích xuất bởi một bộ theo dõi cao độ) cộng với một mô tả văn bản, sinh ra một bản phối đầy đủ đi theo giai điệu huýt sáo theo phong cách được mô tả bởi văn bản.

MusicGen: Sinh tạo Hiệu quả một Giai đoạn

  • MusicGen (Copet và cộng sự, 2023) đơn giản hóa cách tiếp cận đa giai đoạn. Thay vì các mô hình ngữ nghĩa và âm học riêng biệt, MusicGen dùng một transformer tự hồi quy duy nhất trực tiếp sinh nhiều mức codebook từ codec âm thanh. Đổi mới then chốt là một mẫu codebook xen kẽ (interleaved codebook pattern): thay vì sinh tất cả các mức codebook cho một bước thời gian trước khi chuyển sang bước tiếp theo, MusicGen xen kẽ các token xuyên suốt các codebook và bước thời gian theo một mẫu cho phép giải mã song song một số mức codebook.

  • Điều kiện hóa khá trực tiếp: văn bản được mã hóa bởi một bộ mã hóa T5, và các embedding văn bản được đặt trước (prepend) vào chuỗi token âm thanh (như một prompt tiền tố trong mô hình ngôn ngữ) hoặc được đưa vào qua cơ chế chú ý chéo. MusicGen cũng hỗ trợ điều kiện hóa giai điệu: một chromagram (từ các đặc trưng spectrogram đã thảo luận ở Chương 9) của một giai điệu tham chiếu được mã hóa và dùng cùng với điều kiện văn bản.

\[p(a_1, \ldots, a_T) = \prod_{t=1}^{T} \prod_{k=1}^{K} p(a_{t,k} \mid a_{<t}, c_{\text{text}})\]
  • trong đó \(a_{t,k}\) là token âm thanh tại bước thời gian \(t\) và mức codebook \(k\), và \(c_{\text{text}}\) là điều kiện văn bản. Tích trên \(k\) được phân tích tùy theo mẫu codebook — một số mức được dự đoán song song.

Quy trình văn bản-sang-âm thanh: văn bản được mã hóa bởi mô hình ngôn ngữ, bộ giải mã transformer sinh ra các token âm thanh rời rạc qua nhiều mức codebook theo mẫu xen kẽ, bộ giải mã codec âm thanh tái tạo dạng sóng

Sinh tạo Ảnh-sang-Văn bản

  • Giờ hãy đảo ngược hướng: cho một bức ảnh, sinh ra một mô tả ngôn ngữ tự nhiên. Đây là mô tả ảnh (image captioning), và nó là một dạng sinh văn bản có điều kiện với bức ảnh làm điều kiện. Hãy hình dung một hướng dẫn viên bảo tàng đang mô tả một bức tranh — họ phải nhận thức nội dung thị giác, hiểu các quan hệ giữa các vật thể, và diễn đạt quan sát của họ bằng ngôn ngữ trôi chảy.

Mô tả ảnh như Sinh tạo Có điều kiện

  • Cách tiếp cận kinh điển dùng một kiến trúc encoder-decoder (Chương 07). Một CNN hoặc ViT (Chương 8) đã huấn luyện trước mã hóa bức ảnh thành một tập các vector đặc trưng. Một bộ giải mã mô hình ngôn ngữ sinh ra chú thích từng từ một, chú ý đến các đặc trưng ảnh tại mỗi bước:
\[p(w_1, \ldots, w_L \mid I) = \prod_{l=1}^{L} p(w_l \mid w_1, \ldots, w_{l-1}, I)\]
  • trong đó \(w_l\) là các từ trong chú thích và \(I\) là biểu diễn ảnh. Cơ chế chú ý chéo nối bộ giải mã văn bản với các đặc trưng ảnh, cho phép mô hình "nhìn vào" các vùng khác nhau của ảnh khi nó sinh các từ khác nhau — chú ý đến vùng chú chó khi sinh từ "chó" và vùng công viên khi sinh từ "công viên".

  • CoCa (Contrastive Captioners, Yu và cộng sự, 2022) thống nhất học đối lập (mục tiêu kiểu CLIP của file 01) với mô tả ảnh trong một mô hình duy nhất. Bộ mã hóa ảnh sinh ra các đặc trưng được dùng cả cho căn chỉnh đối lập với văn bản và cho cơ chế chú ý chéo trong một bộ giải mã mô tả ảnh. Việc huấn luyện đa nhiệm này cho CoCa khả năng nhận biết zero-shot mạnh (từ học đối lập) và khả năng sinh mạnh (từ mô tả ảnh).

Mô tả ảnh Thị giác-Ngôn ngữ Hiện đại

  • Các cách tiếp cận hiện đại thường dùng các mô hình đa phương thức lớn (large multimodal models) (file 02) cho việc mô tả ảnh. Các mô hình như LLaVA, Qwen-VL, và GPT-4V coi mô tả ảnh như một trường hợp đặc biệt của trả lời câu hỏi thị giác — "câu hỏi" ngầm định là "mô tả bức ảnh này". Bộ mã hóa thị giác (CLIP ViT hoặc SigLIP) sinh ra các token patch được chiếu vào không gian embedding của LLM, và LLM sinh ra một mô tả tự do.

  • Ưu điểm của mô tả ảnh dựa trên LLM so với các mô hình encoder-decoder chuyên dụng là tuân theo chỉ dẫn (instruction following): bạn có thể yêu cầu các mức độ chi tiết khác nhau ("mô tả trong một câu" so với "cung cấp một đoạn văn chi tiết"), tập trung vào các khía cạnh cụ thể ("mô tả các màu sắc"), hoặc sinh ra đầu ra có cấu trúc ("liệt kê tất cả các vật thể kèm vị trí của chúng"). Sự linh hoạt này đến từ việc tinh chỉnh chỉ dẫn (instruction-tuning) của LLM (Chương 07).

Sinh tạo Đồng thời Video-Âm thanh

  • Hãy hình dung xem một bộ phim với âm thanh tắt — trải nghiệm trở nên rỗng tuếch. Nội dung thị giác và âm thanh gắn kết sâu sắc với nhau: một quả bóng nảy có tiếng bộp theo nhịp, mưa tạo ra tiếng lộp độp, và một đám đông tạo ra tiếng reo hò. Sinh tạo đồng thời video-âm thanh (video-audio co-generation) nhằm sinh ra cả hai phương thức cùng lúc, duy trì sự căn chỉnh theo thời gian giữa những gì bạn thấy và những gì bạn nghe.

Mô hình hóa Thời gian Chung

  • Thách thức cốt lõi là đồng bộ hóa theo thời gian (temporal synchronisation): âm thanh của một tiếng gõ trống phải trùng khớp chính xác với khung hình hiển thị dùi trống đánh vào trống. Điều này đòi hỏi một biểu diễn thời gian chung mà cả hai phương thức đều có thể tham chiếu.

  • Một cách tiếp cận là sinh video và âm thanh từ một dòng thời gian tiềm ẩn chung. Các mô hình như CoDi (Composable Diffusion, Tang và cộng sự, 2023) dùng các mô hình khuếch tán riêng biệt cho mỗi phương thức nhưng căn chỉnh chúng qua một không gian tiềm ẩn chung. Trong quá trình huấn luyện, các lớp cơ chế chú ý xuyên phương thức học cách đồng bộ hóa các đặc trưng thị giác và âm thanh tại mỗi bước thời gian. Trong quá trình sinh, cả hai quy trình khuếch tán chạy đồng thời, điều kiện hóa lẫn nhau qua sự căn chỉnh chung.

  • VideoPoet (đã thảo luận ở trên) dùng một cách tiếp cận thống nhất hơn: vì tất cả các phương thức đều được token hóa thành một chuỗi duy nhất, LLM tự nhiên học được các tương ứng thời gian giữa các token video và âm thanh. Một đoạn video chú chó sủa theo sau bởi các token âm thanh tương ứng dạy mô hình liên kết chuyển động sủa thị giác với âm thanh sủa.

  • Các hàm hàm mất mát căn chỉnh theo thời gian (temporal alignment loss) thực thi rõ ràng sự đồng bộ. Một công thức dùng học đối lập ở cấp độ khung hình: đoạn âm thanh tại thời gian \(t\) nên tương đồng hơn với khung hình video tại thời gian \(t\) so với các khung hình ở thời gian khác:

\[\mathcal{L}_{\text{sync}} = -\mathbb{E}_t \left[\log \frac{\exp(\text{sim}(v_t, a_t) / \tau)}{\sum_{t'} \exp(\text{sim}(v_t, a_{t'}) / \tau)}\right]\]
  • trong đó \(v_t\)\(a_t\) là các biểu diễn video và âm thanh tại thời gian \(t\), và \(\tau\) là một tham số nhiệt độ. Công thức này về cấu trúc giống hệt với mất mát InfoNCE từ file 01, nhưng được áp dụng ở cấp độ khung hình thời gian thay vì cấp độ đoạn (clip).

Sinh tạo Tuân theo Chỉ dẫn

  • Hãy hình dung bảo một họa sĩ "làm bầu trời kịch tính hơn" hoặc "thay cái mũ bằng một chiếc vương miện". Sinh tạo tuân theo chỉ dẫn (instruction-following generation) cho phép bạn chỉnh sửa ảnh bằng các lệnh ngôn ngữ tự nhiên thay vì các mặt nạ không gian chính xác hay các nét cọ.

InstructPix2Pix: Chỉnh sửa bằng Mô tả

  • InstructPix2Pix (Brooks và cộng sự, 2023) huấn luyện một mô hình khuếch tán có điều kiện nhận một ảnh đầu vào và một chỉ dẫn văn bản, rồi sinh ra ảnh đã chỉnh sửa. Phần khéo léo nằm ở cách dữ liệu huấn luyện được tạo ra: GPT-3 sinh ra các chỉ dẫn chỉnh sửa ("làm nó thành mùa đông", "biến con mèo thành con chó") đi kèm với các chú thích văn bản đầu vào-đầu ra, và một mô hình văn bản-sang-ảnh (Stable Diffusion) sinh ra các cặp ảnh tương ứng.

  • Mô hình là một U-Net Stable Diffusion đã biến đổi nhận cả chỉ dẫn văn bản (qua chú ý chéo) và latent ảnh đầu vào (nối kênh với latent nhiễu). Nó dùng classifier-free guidance kép (dual classifier-free guidance) với hai thang hướng dẫn — một cho chỉ dẫn văn bản (\(s_T\)) và một cho ảnh đầu vào (\(s_I\)):

\[\hat{\epsilon} = \epsilon_\theta(x_t, \varnothing, \varnothing) + s_I \cdot (\epsilon_\theta(x_t, c_I, \varnothing) - \epsilon_\theta(x_t, \varnothing, \varnothing)) + s_T \cdot (\epsilon_\theta(x_t, c_I, c_T) - \epsilon_\theta(x_t, c_I, \varnothing))\]
  • trong đó \(c_I\) là điều kiện ảnh đầu vào và \(c_T\) là chỉ dẫn văn bản. Số hạng hướng dẫn thứ nhất kiểm soát mức độ bảo toàn ảnh đầu vào; số hạng thứ hai kiểm soát mức độ tuân theo chỉ dẫn. Điều này cho người dùng một nút vặn hai chiều: \(s_I\) cao bảo toàn bản gốc sát sao, trong khi \(s_T\) cao tạo ra các chỉnh sửa kịch tính hơn.

InstructPix2Pix: ảnh đầu vào và chỉ dẫn văn bản được đưa vào một mô hình khuếch tán đã biến đổi, tạo ra ảnh đã chỉnh sửa tuân theo chỉ dẫn trong khi giữ nguyên các vùng không bị sửa

SDEdit và Chỉnh sửa dựa trên Nhiễu

  • SDEdit (Meng và cộng sự, 2022) đề xuất một cách chỉnh sửa đơn giản hơn không đòi hỏi huấn luyện đặc biệt. Bạn lấy ảnh đầu vào, thêm nhiễu vào nó (chạy quá trình khuếch tán tiến đến một bước thời gian trung gian \(t_0\)), rồi khử nhiễu với một câu lệnh văn bản mô tả đầu ra mong muốn. Lượng nhiễu kiểm soát cường độ chỉnh sửa: nhiễu thấp bảo toàn cấu trúc (thay đổi màu sắc, chuyển phong cách), trong khi nhiễu cao cho phép tái cấu trúc lớn (thay thế vật thể, thay đổi bố cục).

  • Sự đánh đổi là rõ ràng: tại bước thời gian \(t_0\), ảnh nhiễu giữ lại phần \(\bar{\alpha}_{t_0}\) của tín hiệu gốc. Quá trình khử nhiễu lấp đầy các chi tiết bị hỏng theo câu lệnh văn bản mới. Điều này có nền tảng toán học: mô hình khuếch tán lấy mẫu từ hậu nghiệm \(p(x_0 \mid x_{t_0}, c)\), với \(x_{t_0}\) ràng buộc việc sinh phải "gần với" bản gốc.

ControlNet: Điều kiện hóa Không gian

  • ControlNet (Zhang và cộng sự, 2023) thêm điều khiển không gian tinh tế vào khuếch tán văn bản-sang-ảnh. Một bản sao của bộ mã hóa U-Net đã huấn luyện trước được huấn luyện để nhận các điều kiện đầu vào bổ sung — bản đồ cạnh (Canny edges), bản đồ độ sâu, khung xương tư thế (pose skeletons), bản đồ phân đoạn — trong khi các trọng số U-Net gốc được đóng băng. Đầu ra của bộ mã hóa ControlNet được cộng vào các kết nối bỏ qua (skip connections) của U-Net đã đóng băng qua các phép tích chập không (zero convolutions) (tích chập 1x1 khởi tạo bằng không), đảm bảo huấn luyện bắt đầu từ hành vi của mô hình đã huấn luyện trước và dần học điều kiện mới.

  • Kiến trúc này cho phép bạn cung cấp một bản phác thảo, một bản đồ độ sâu, hoặc một tư thế người làm hướng dẫn cấu trúc, và câu lệnh văn bản sẽ lấp đầy phần ngoại hình. Các trọng số đã huấn luyện trước lo phần quang học thực tế và hiểu văn bản; các lớp ControlNet lo phần trung thực không gian với điều kiện.

Các Chỉ số Nhất quán và Căn chỉnh

  • Làm sao để đo lường một bức ảnh sinh ra có tốt hay không? "Tốt" có ít nhất hai khía cạnh: chất lượng (nó có trông giống một ảnh thật không?) và sự căn chỉnh (alignment) (nó có khớp với câu lệnh văn bản không?). Một số chỉ số đã được phát triển để lượng hóa những điều này.

Frechet Inception Distance (FID)

  • Frechet Inception Distance (FID) (Heusel và cộng sự, 2017) đo khoảng cách giữa phân bố của các ảnh sinh ra và ảnh thật trong không gian đặc trưng của một mạng Inception đã huấn luyện trước. Hãy coi nó như so sánh "dấu vân tay" của hai tập hợp ảnh thay vì so sánh từng ảnh riêng lẻ.

  • Cả tập ảnh thật và ảnh sinh đều được đưa qua Inception-v3, và các kích hoạt (activations) từ lớp áp chót được thu thập. Các kích hoạt này được mô hình hóa như các Gaussian đa biến \(\mathcal{N}(\mu_r, \Sigma_r)\)\(\mathcal{N}(\mu_g, \Sigma_g)\). FID là khoảng cách Frechet (khoảng cách Wasserstein-2) giữa các Gaussian này:

\[\text{FID} = \|\mu_r - \mu_g\|^2 + \text{Tr}\left(\Sigma_r + \Sigma_g - 2(\Sigma_r \Sigma_g)^{1/2}\right)\]
  • FID thấp hơn là tốt hơn. FID = 0 nghĩa là các phân bố giống hệt nhau. FID nắm bắt cả chất lượng (nếu ảnh sinh bị mờ, các đặc trưng của chúng sẽ khác với ảnh thật) và độ đa dạng (nếu mô hình bị sụp mode, \(\Sigma_g\) sẽ nhỏ hơn \(\Sigma_r\)). Các giá trị tiên tiến hiện nay trên ImageNet 256x256 thường là FID < 2.0.

  • FID có những hạn chế đã biết: nó giả định phân bố đặc trưng là Gaussian (chỉ là xấp xỉ), nó đòi hỏi hàng ngàn mẫu để có ước lượng ổn định, và nó dùng các đặc trưng Inception (có thể không nắm bắt được mọi khác biệt liên quan đến nhận thức).

Inception Score (IS)

  • Inception Score (IS) (Salimans và cộng sự, 2016) đo hai thuộc tính: mỗi ảnh sinh ra nên được phân lớp tự tin (phân bố lớp có điều kiện \(p(y \mid x)\) nên nhọn), và tập các ảnh sinh ra nên bao phủ nhiều lớp (biên \(p(y) = \mathbb{E}_x[p(y \mid x)]\) nên đều). IS kết hợp chúng qua phân kỳ KL:
\[\text{IS} = \exp\left(\mathbb{E}_x \left[D_{\text{KL}}(p(y \mid x) \| p(y))\right]\right)\]
  • IS cao hơn là tốt hơn. IS tối đa bằng số lượng lớp (1000 cho ImageNet). IS thưởng cho chất lượng (ảnh sắc nét, nhận diện được) và độ đa dạng (bao phủ các lớp), nhưng nó có những hạn chế đáng kể: nó hoàn toàn bỏ qua phân bố dữ liệu thật, không thể phát hiện sụp mode trong một lớp, và bị thiên vị về các ảnh giống ImageNet vì nó dùng các dự đoán lớp của Inception.

CLIPScore: Đo lường Căn chỉnh Văn bản-Ảnh

  • CLIPScore (Hessel và cộng sự, 2021) đo lường trực tiếp một bức ảnh sinh ra khớp với câu lệnh văn bản của nó đến mức nào bằng một mô hình CLIP đã huấn luyện trước (file 01). Điểm số đơn giản chỉ là độ tương đồng cosin giữa embedding ảnh CLIP và embedding văn bản CLIP:
\[\text{CLIPScore}(I, T) = \max(0, \cos(E_I(I), E_T(T)))\]
  • trong đó \(E_I\)\(E_T\) là các bộ mã hóa ảnh và văn bản CLIP. CLIPScore không cần tham chiếu (reference-free) — nó không đòi hỏi ảnh thực tế, chỉ cần câu lệnh văn bản. Nó tương quan tốt với đánh giá của con người về sự căn chỉnh văn bản-ảnh và đã trở thành chỉ số tiêu chuẩn để đánh giá độ trung thực với câu lệnh (prompt fidelity) trong các mô hình văn bản-sang-ảnh.

  • Để so sánh với một chú thích tham chiếu, RefCLIPScore kết hợp một ảnh tham chiếu:

\[\text{RefCLIPScore} = \text{HarmonicMean}(\text{CLIPScore}(I, T), \max(0, \cos(E_I(I), E_I(I_{\text{ref}}))))\]
  • Điều này cân bằng giữa căn chỉnh văn bản và sự tương đồng thị giác với một ảnh tham chiếu.

Các chỉ số đánh giá: FID so sánh phân bố đặc trưng của tập ảnh thật và ảnh sinh, IS đo chất lượng và độ đa dạng của ảnh sinh, CLIPScore đo độ tương đồng cosin giữa embedding ảnh và văn bản

Đánh giá bởi Con người

  • Các chỉ số tự động chỉ là đại diện xấp xỉ; đánh giá của con người vẫn là tiêu chuẩn vàng. Các quy trình phổ biến gồm so sánh từng cặp (pairwise comparisons) (trong hai ảnh, ảnh nào khớp câu lệnh hơn?), thang Likert (đánh giá chất lượng và sự căn chỉnh từ 1-5), và xếp hạng Elo (xếp hạng kiểu giải đấu xuyên các mô hình). Các benchmark DrawBench và PartiPrompts cung cấp các tập câu lệnh chuẩn hóa cho việc đánh giá bởi con người một cách có hệ thống.

Các Cân nhắc về Đạo đức

  • Sinh tạo đa phương thức là một trong những lĩnh vực có hệ quả đạo đức lớn nhất trong AI. Khả năng tạo ra các ảnh, video, và âm thanh siêu thực từ các mô tả văn bản đặt ra những lo ngại sâu sắc mà những người thực hành phải xem xét nghiêm túc.

Deepfake và Thông tin sai lệch

  • Deepfake là các phương tiện được sinh ra hoặc thao túng nhằm mô tả các sự kiện chưa từng xảy ra. Các mô hình văn bản-sang-ảnh và văn bản-sang-video có thể tạo ra những bức ảnh giả thuyết phục về những nhân vật của công chúng, bằng chứng bịa đặt, và hình ảnh tin tức gây hiểu lầm. Nguy hiểm không chỉ ở chỗ các nội dung giả tồn tại, mà ở việc sự tồn tại của chúng làm xói mòn niềm tin vào mọi phương tiện — nếu bất kỳ ảnh nào cũng có thể là giả, thì không có ảnh nào được tin hoàn toàn.

  • Các phương pháp phát hiện bao gồm huấn luyện các bộ phân lớp trên ảnh thật so với ảnh sinh, phân tích các artefact thống kê (ảnh sinh bởi GAN có những chữ ký phổ (spectral signatures) tinh tế), và nhúng các thủy ấn (watermark) vô hình (thủy ấn vô hình của Stable Diffusion, SynthID của Google). Tuy nhiên, phát hiện là một cuộc đua vũ trang: khi các bộ sinh cải thiện, các bộ phát hiện phải liên tục được cập nhật.

Thiên kiến trong Sinh tạo

  • Các mô hình được huấn luyện trên dữ liệu quy mô internet kế thừa và khuếch đại các thiên kiến xã hội. Các mô hình văn bản-sang-ảnh sinh ra thiên lệch các khuôn mặt da sáng hơn, liên kết một số nghề nghiệp nhất định với giới tính cụ thể, và mặc định các chuẩn mực văn hóa phương Tây cho các câu lệnh thiếu định rõ. Những thiên kiến này bắt nguồn từ phân bố dữ liệu huấn luyện và các bộ mã hóa văn bản CLIP/T5, vốn mã hóa các thiên kiến từ kho ngữ liệu huấn luyện của chính chúng.

  • Các chiến lược giảm thiểu bao gồm tuyển chọn dữ liệu huấn luyện mang tính đại diện hơn, áp dụng các kỹ thuật khử thiên kiến cho các bộ mã hóa văn bản, dùng các bộ phân lớp an toàn để lọc các đầu ra có vấn đề, và cho phép người dùng kiểm soát các thuộc tính nhân khẩu học. Không có giải pháp nào là hoàn chỉnh, và việc kiểm toán liên tục là thiết yếu.

Lọc nội dung và An toàn

  • Triển khai có trách nhiệm đòi hỏi nhiều lớp bảo vệ. Lọc đầu vào (input filtering) chặn các câu lệnh có hại trước khi sinh. Lọc đầu ra (output filtering) phân lớp nội dung sinh ra và từ chối vật liệu có hại. Các bộ phân lớp NSFW phát hiện nội dung khiêu dâm, bạo lực, hoặc có hại khác. Chẳng hạn, bộ kiểm tra an toàn (safety checker) của Stable Diffusion tính độ tương đồng cosin giữa embedding CLIP của ảnh sinh ra và một tập các embedding khái niệm có hại đã định nghĩa trước, gắn cờ các ảnh vượt quá một ngưỡng.

  • Bản chất mã nguồn mở của nhiều mô hình sinh (Stable Diffusion, Wan) tạo ra sự căng thẳng giữa việc dân chủ hóa quyền truy cập và ngăn chặn lạm dụng. Một khi trọng số mô hình được phát hành, việc lọc nội dung có thể bị vô hiệu hóa. Điều này đã dẫn đến những tranh luận về mức độ cởi mở thích hợp và trách nhiệm của những người phát triển mô hình.

Sở hữu Trí tuệ và Sự đồng ý

  • Các mô hình sinh được huấn luyện trên dữ liệu internet có thể tái tạo các phong cách có bản quyền, nhãn hiệu, hoặc hình ảnh của người thật mà không có sự đồng ý. Các khung pháp lý và đạo đức vẫn đang phát triển, nhưng thực hành có trách nhiệm bao gồm tôn trọng các cơ chế từ chối (opt-out), công nhận những đóng góp sáng tạo được nhúng trong dữ liệu huấn luyện, và phát triển các biện pháp bảo vệ kỹ thuật chống lại việc ghi nhớ và nhả lại (regurgitation) các ví dụ huấn luyện.

Bài tập lập trình (dùng CoLab hoặc notebook)

  1. Triển khai classifier-free guidance cho một mô hình khuếch tán 2D đồ chơi. Huấn luyện một mô hình khuếch tán có điều kiện trên một tập dữ liệu 2D (ví dụ: các cụm có nhãn), rồi lấy mẫu với các thang hướng dẫn khác nhau để quan sát sự đánh đổi chất lượng-đa dạng.
import jax
import jax.numpy as jnp
import matplotlib.pyplot as plt

# Toy 2D conditional diffusion with classifier-free guidance
def noise_schedule(T):
    betas = jnp.linspace(1e-4, 0.02, T)
    alphas = 1.0 - betas
    return jnp.cumprod(alphas)

def forward_diffuse(x0, t, alpha_bars, key):
    noise = jax.random.normal(key, x0.shape)
    return jnp.sqrt(alpha_bars[t]) * x0 + jnp.sqrt(1 - alpha_bars[t]) * noise, noise

# Generate labelled 2D data: class 0 = ring, class 1 = cluster
key = jax.random.PRNGKey(42)
k1, k2, k3 = jax.random.split(key, 3)
theta = jax.random.uniform(k1, (200,)) * 2 * jnp.pi
ring = jnp.stack([jnp.cos(theta), jnp.sin(theta)], axis=1) * 2
ring += jax.random.normal(k2, ring.shape) * 0.1
cluster = jax.random.normal(k3, (200, 2)) * 0.3

data = jnp.concatenate([ring, cluster])
labels = jnp.concatenate([jnp.zeros(200), jnp.ones(200)])

# Simulate CFG: show how guidance pushes samples toward class-conditional modes
# Try varying guidance_scale from 0.0 to 5.0 and observe results
guidance_scales = [0.0, 1.0, 3.0, 7.0]
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
for ax, s in zip(axes, guidance_scales):
    ax.scatter(ring[:, 0], ring[:, 1], s=8, alpha=0.4, label='Ring (c=0)')
    ax.scatter(cluster[:, 0], cluster[:, 1], s=8, alpha=0.4, label='Cluster (c=1)')
    ax.set_title(f'Guidance scale s={s}')
    ax.set_xlim(-4, 4); ax.set_ylim(-4, 4)
    ax.set_aspect('equal'); ax.legend(fontsize=7)
plt.suptitle('Experiment: vary guidance scale and observe quality vs diversity')
plt.tight_layout(); plt.show()
# Exercise: train a small MLP denoiser with class conditioning,
# then implement the CFG formula to sample with different s values.
  1. Tính FID giữa hai tập mẫu 2D bằng công thức khoảng cách Frechet đầy đủ. Thay đổi phân bố sinh và quan sát FID thay đổi ra sao.
import jax
import jax.numpy as jnp
import matplotlib.pyplot as plt

def compute_fid(real, generated):
    """Compute Frechet distance between two 2D sample sets."""
    mu_r, mu_g = jnp.mean(real, axis=0), jnp.mean(generated, axis=0)
    sigma_r = jnp.cov(real.T)
    sigma_g = jnp.cov(generated.T)
    diff = mu_r - mu_g
    # Matrix square root via eigendecomposition
    product = sigma_r @ sigma_g
    eigvals, eigvecs = jnp.linalg.eigh(product)
    sqrt_product = eigvecs @ jnp.diag(jnp.sqrt(jnp.maximum(eigvals, 0))) @ eigvecs.T
    fid = jnp.sum(diff ** 2) + jnp.trace(sigma_r + sigma_g - 2 * sqrt_product)
    return fid

key = jax.random.PRNGKey(0)
k1, k2, k3, k4 = jax.random.split(key, 4)

# Real distribution: standard 2D Gaussian
real = jax.random.normal(k1, (1000, 2))

# Generated distributions with increasing divergence
shifts = [0.0, 0.5, 1.0, 2.0, 4.0]
fig, axes = plt.subplots(1, len(shifts), figsize=(18, 3.5))
for ax, shift in zip(axes, shifts):
    gen = jax.random.normal(k2, (1000, 2)) * (1 + shift * 0.2) + shift
    fid = compute_fid(real, gen)
    ax.scatter(real[:, 0], real[:, 1], s=3, alpha=0.3, label='Real')
    ax.scatter(gen[:, 0], gen[:, 1], s=3, alpha=0.3, label='Generated')
    ax.set_title(f'Shift={shift}\nFID={fid:.2f}')
    ax.set_xlim(-5, 8); ax.set_ylim(-5, 8)
    ax.set_aspect('equal'); ax.legend(fontsize=7)
plt.suptitle('FID increases as generated distribution diverges from real')
plt.tight_layout(); plt.show()
# Try: change the variance of generated samples without shifting the mean.
# How does FID respond to a diversity mismatch vs a location mismatch?
  1. Triển khai tính toán CLIPScore giữa các embedding văn bản và ảnh dùng các phép chiếu ngẫu nhiên làm thay thế cho CLIP. Quan sát cách độ tương đồng cosin hoạt động khi bạn thay đổi "sự căn chỉnh" giữa các phương thức.
import jax
import jax.numpy as jnp
import matplotlib.pyplot as plt

def cosine_similarity(a, b):
    return jnp.dot(a, b) / (jnp.linalg.norm(a) * jnp.linalg.norm(b))

def clip_score(img_emb, txt_emb):
    """CLIPScore: clamped cosine similarity."""
    return jnp.maximum(0.0, cosine_similarity(img_emb, txt_emb))

key = jax.random.PRNGKey(42)
dim = 512  # CLIP embedding dimension

# Simulate aligned and misaligned pairs
# Aligned: image and text embeddings share a component
k1, k2, k3 = jax.random.split(key, 3)
shared = jax.random.normal(k1, (dim,))
shared = shared / jnp.linalg.norm(shared)

noise_levels = jnp.linspace(0, 5, 20)
scores = []
for noise in noise_levels:
    noise_vec = jax.random.normal(k2, (dim,)) * noise
    img_emb = shared + noise_vec * 0.3
    txt_emb = shared + jax.random.normal(k3, (dim,)) * noise * 0.3
    scores.append(float(clip_score(img_emb, txt_emb)))

plt.figure(figsize=(8, 4))
plt.plot(noise_levels, scores, 'o-', color='#2c3e50')
plt.xlabel('Noise level (misalignment)')
plt.ylabel('CLIPScore')
plt.title('CLIPScore decreases as text-image alignment degrades')
plt.grid(True, alpha=0.3)
plt.tight_layout(); plt.show()
# Experiment: what happens if you normalise embeddings before adding noise?
# How does dimensionality affect the score distribution?