Giới thiệu bài lab
Lab Qwen-Image-2.1: chạy thử vòng khử nhiễu 3 bước thu nhỏ từ 1A đến 6B bằng NumPy
Bài lab là một script Python dùng NumPy (thư viện tính toán trên mảng số) chạy ngay trong trình duyệt. Nó dựng lại cả 10 khối 1A đến 6B ở kích thước thu nhỏ: vector 8 chiều thay vì 4096, 2 lớp thay vì 32, 3 bước Euler thay vì 8. Chuỗi token gồm 11 phần tử: 7 token Prefix (chữ và ảnh tham chiếu, phần đứng trước) cộng 4 token của ảnh đích đang được khử nhiễu.
Ý tưởng cốt lõi của kiến trúc là tính phần Prefix một lần rồi dùng lại. Lab cho bạn tự thấy điều đó bằng số: kết quả dùng cache và kết quả tính lại toàn bộ chuỗi chỉ khác nhau cỡ 2.22e-16 (tức 2.22 × 10 mũ −16, gần như bằng 0).
Bài lab gồm
- Sơ đồ 4 cột có khung tương tác ở đầu trang, để biết mỗi bảng số thuộc khối nào.
- Bảng ánh xạ 1:1 cho từng mã 1A đến 6B: lab dựng gì và nhìn số nào để kiểm chứng.
- Trình chạy trực tiếp với mã
qwen-image-21.pysửa được, và các nút Chạy cell, Dừng, Đặt lại. - Output chia thành các khối [1A] đến [6B], rồi mục [KIỂM TRA & THỬ NGHIỆM] với 3 phép kiểm chứng tự động.
- Trang bài đọc Lab đầy đủ (liên kết ở thanh công cụ) có hướng dẫn chi tiết và 4 bài tập kèm đáp án.
Làm xong, bạn có thể
- Đọc bản đồ image_ids = [-1, -1, 0, 0, 0, 0, -1, 1, 1, 1, 1] và target_token_mask để nói token nào là chữ, ảnh tham chiếu hay ảnh đích.
- Đếm khóa hợp lệ trên từng hàng của mặt nạ Block-Causal 11×11 và giải thích vì sao token chữ ở vị trí 1 thấy 2 khóa còn token ảnh đầu tiên ở vị trí 2 thấy 6 khóa.
- Giải thích vì sao tắt điều kiện t = 0 khiến vector K (Key) của Prefix bị trôi (lệch cỡ 9.61e-01 đến 1.68e+00) làm cache mất tác dụng.
- Giải thích vì sao Steps 2 và 3 chỉ cần tính 4 token ảnh đích mà vẫn ra kết quả khớp tính lại toàn bộ 11 token.
- Nói được lab chứng minh gì (cơ chế cache và mặt nạ tính đúng) và không chứng minh gì (chất lượng ảnh, tốc độ GPU).
Phạm vi: lab chỉ chạy suy luận (forward) của một mô hình thu nhỏ và không có bước huấn luyện; trọng số là số ngẫu nhiên cố định bằng seed 21, nên ảnh RGBA 2×2 cuối cùng chỉ cho thấy luồng tính đúng, không phải ảnh đẹp. Muốn học huấn luyện, hãy xem khóa LLM Training (Text), vốn chỉ dạy mô hình văn bản; huấn luyện mô hình tạo ảnh từ nhiễu chưa có bài nào trên site.
Cách dùng bài lab
- Xem sơ đồ 4 cột ở đầu trang: rê chuột hoặc bấm vào khung để mở pop-over, các nút lọc theo cột làm mờ khung của những cột còn lại, và nút Ẩn khung overlay cho bạn đọc ảnh gốc.
- Đọc bảng ánh xạ bên dưới: cột thứ ba cho biết lab dựng gì ở mỗi mã, cột thứ tư cho biết nhìn số nào để kiểm chứng.
- Đọc cấu hình thu nhỏ ở đầu mã: ảnh điều kiện 2×2 với 4 kênh RGBA, ngữ cảnh Qwen3-VL gồm 4 slot [chữ, chữ, ảnh, chữ],
TURBO_SIGMAS = (1.0, 0.85, 0.45, 0.0)tức 3 bước Euler, vàSEED = 21. - Dự đoán trước rồi bấm Chạy cell. Ở [1A] đến [2A], kiểm tra image_ids và target_token_mask: 7 chữ F (Prefix) đứng trước 4 chữ T (ảnh đích).
- Ở [3A] đến [3C], đối chiếu tọa độ của hai khối ảnh, xem hàng t = 0.0 của bảng điều biến giữ nguyên khi t đổi từ 1000 sang 850, và đếm khóa hợp lệ trên từng hàng mặt nạ.
- Ở [4A] đến [6B], so cached_k kích thước (7, 2, 4) của Step 1 với 4 token ảnh đích tính ở Steps 2 và 3, rồi đọc [KIỂM TRA & THỬ NGHIỆM]. Có thể sửa mã và chạy lại; một số hằng số như
VLM_IMG_MASKcó assert giữ chuỗi ở 7 + 4 token nên đổi sai sẽ báo lỗi, và nút Đặt lại khôi phục mã gốc.
Đọc kết quả đúng cách: 3 phép kiểm chứng chỉ nói rằng cơ chế cache và mặt nạ tính đúng với trọng số ngẫu nhiên; chúng không nói ảnh đẹp hay mô hình nhanh hơn.
| Mã | Thành phần ở Tab 01 (bấm để mở bài) | Lab NumPy dựng gì (`qwen-image-21.py`) | Cách đọc số liệu & phép kiểm chứng |
|---|---|---|---|
| 1A | RGBA 64-Channel VAE & Unpatched Latents ↗ | Chuẩn hóa 4 pixel RGBA (2×2×4) qua z = (z − mean)/std và chiếu thẳng qua img_in với PATCH_SIZE = 1 (4 → 8). | Đối chiếu vector sau chuẩn hóa và sau img_in: denoise luôn diễn ra trong không gian chuẩn hóa. |
| 1B | Qwen3-VL Context & Zero-Center RMSNorm (w + 1) ↗ | Chuẩn hóa chuỗi ngữ cảnh VLM bằng rsqrt(mean(x²) + ε) · (w + 1) và chiếu qua MLP 2 tầng GELU. | Kiểm tra các slot văn bản đi qua txt_in GELU MLP trong khi vector slot ảnh được giữ nguyên để mở rộng ở 2A. |
| 2A | Mở rộng 4× Slot ảnh (2×2) & Ghép chuỗi đồng nhất ↗ | Dùng repeats = [1, 1, 4, 1] bung slot ảnh VLM thành 4 vị trí và nối thêm 4 token ảnh đích → S_joint = 11 (prefix 7 + target 4). | Kiểm tra image_ids = [-1, -1, 0, 0, 0, 0, -1, 1, 1, 1, 1] và target_token_mask đánh dấu đúng 4 vị trí cuối. |
| 3A | 3D Axial RoPE (Frame, Height, Width) & Lưới tâm không ↗ | Token chữ tăng đều cả 3 trục (0,0,0) → (1,1,1) → (2,2,2); hai khối ảnh 2×2 ghim frame = 0 và căn tâm [(-1,-1), (-1,0), (0,-1), (0,0)]. | Xác nhận tọa độ không gian (h, w) của ảnh tham chiếu và ảnh đích trùng khớp, không phụ thuộc vị trí đứng trong câu. |
| 3B | Điều kiện nhân quả (t=0 vs t) & Shared Modulation ↗ | Tạo bảng modulation 2 hàng [t_step, 0.0]: 7 token Prefix luôn đọc hàng t = 0.0, còn 4 token Target đọc hàng t_step. | So sánh Step 1 (t=1000) và Step 2 (t=850): hàng 1 (t=0.0) lệch đúng 0.00e+00 trong khi hàng 0 đổi theo bước nhiễu. |
| 3C | Mặt nạ Block-Causal 11×11 (Nhân quả + Hai chiều) ↗ | Dựng ma trận 11×11 theo quy tắc (q >= kv) OR (q_img_id == kv_img_id >= 0). | Kiểm chứng (3): đổi token target (pos 7) gây lệch 0.00e+00 lên 7 token prefix; đổi pixel ảnh điều kiện (pos 5) lan truyền song hướng khắp khối 2..5. |
| 4A | Single-Stream DiT Attention & QK-RMSNorm ↗ | Điều biến LN(x)·(1 + scale1) + shift1, chiếu Q/K/V chung một luồng, chuẩn hóa QK-RMSNorm từng head, xoay 3D RoPE và cộng residual qua tanh(gate1). | Quan sát trọng số attention của token 7 trên cả 11 khóa hợp lệ và biên độ cổng tanh(gate1) ≤ 1. |
| 5A | Mạng SwiGLU có điều biến (3× Ratio) & Cổng Tanh ↗ | Mở rộng chiều ẩn 3× (8 → 24 → 8), nhân cổng SiLU(W_gate x) ⊙ (W_up x) và cộng residual qua tanh(gate2). | Đối chiếu 6 cột đầu của nhánh gate, nhánh up và tích SwiGLU trước khi thu về chiều ẩn gốc. |
| 6A | Prefix KV Cache (Step 1 Extract → Steps 2..3 Cached) ↗ | Step 1 (extract) lưu cached_k, cached_v shape (7, 2, 4); Steps 2–3 (cached) chỉ tính Q/K/V cho 4 token target và ghép cat([cached_k, target_k]). | Kiểm chứng (1) & (2): cached vs recompute toàn trình khớp tới 2.22e-16 (< 1e-9); nếu tắt t=0 trên prefix thì cache bị trôi tới 1.68e+00! |
| 6B | Scale-Only Final AdaLN, Velocity & Vòng lặp Euler → RGBA ↗ | Chuẩn hóa đầu ra LN(h)·(1 + scale_final) không có shift, chiếu ra vận tốc v_θ, tích phân 3 bước Euler (1.0 → 0.85 → 0.45 → 0.0) và giải mã ra ảnh RGBA 2×2×4. | Kiểm tra 4 kênh R, G, B, Alpha đầu ra khớp tuyệt đối (sai lệch 1.11e-16) giữa đường dùng cache và đường tính lại toàn chuỗi. |
Nguồn công bố & mã nguồn tham chiếu
Danh sách bài học (11)
- Lab tổng hợp Qwen-Image-2.1 — chạy toàn trình 1A → 6B bằng NumPy
- 1A · RGBA 64-Channel VAE & Unpatched Latents · Mã hóa ảnh trong suốt 4 kênh
- 1B · Qwen3-VL Context & Zero-Center RMSNorm · Mã hóa ngữ cảnh đa tham chiếu
- 2A · Mở rộng 4× Slot ảnh & Ghép chuỗi đồng nhất (Joint Sequence Packing)
- 3A · 3D Axial RoPE (16, 56, 56) & Lưới tọa độ tâm không (Zero-Centered Grid)
- 3B · Điều kiện nhân quả (t=0 vs t) & Bộ điều biến dùng chung (Shared Modulation)
- 3C · Mặt nạ Block-Causal · Nhân quả trên chữ và hai chiều trong từng khối ảnh
- 4A · Single-Stream DiT Attention (32 lớp) & Chuẩn hóa QK-RMSNorm
- 5A · Mạng SwiGLU có điều biến (3× Ratio) & Cổng Residual Tanh
- 6A · Prefix KV Cache qua các bước khử nhiễu (Extract Step 1 → Cached Steps 2..N)
- 6B · Scale-Only Final AdaLN, Dự đoán vận tốc v_θ & Vòng lặp 8-Step Euler
