Syllabus học TensorFlow - PyTorch
Giai Đoạn 0 - Prerequisites (Ngày 1 - 15)
Mục tiêu giai đoạn: Có đủ nền Python nâng cao, C++ cơ bản, Git/Docker, NumPy và Toán học để bước vào Deep Learning (Giai đoạn 1) mà không bị hổng kiến thức nền.
Ngày 1: Setup môi trường & Git
Mục tiêu: Có môi trường dev chuẩn, biết quản lý version code như một kỹ sư thực thụ.
Lý thuyết: Git cơ bản (commit, branch, merge vs rebase), cấu trúc
.git,.gitignore; Python virtual env (venv/conda) và dependency management (pip, poetry).Thực hành: Tạo repo cho toàn bộ lộ trình, cấu trúc thư mục theo từng Giai đoạn/Ngày, viết README, commit đều đặn từ ngày này trở đi. Setup VSCode/PyCharm + linter (ruff/black) + pytest.
Ngày 2: Docker cơ bản
Mục tiêu: Đóng gói môi trường học tái lập được, chuẩn bị nền cho việc deploy ở Giai đoạn 10.
Lý thuyết: Image vs Container, Dockerfile, layer caching, volume, docker-compose cơ bản.
Thực hành: Viết Dockerfile cho môi trường Python + CUDA (nvidia/cuda base image), build và chạy container, mount volume code, verify
nvidia-smichạy được trong container.
Ngày 3: OOP trong Python
Mục tiêu: Thành thạo OOP ở mức đủ để đọc source code framework sau này (PyTorch dùng OOP rất nhiều).
Lý thuyết: Class, inheritance, MRO (Method Resolution Order), abstract base class, magic methods (
__call__,__getattr__,__enter__), metaclass cơ bản, dataclass.Thực hành: Viết một mini class hierarchy mô phỏng
nn.Module(chỉ với__call__vàforward- chưa cần autograd), dùng__init_subclass__để tự động đăng ký các subclass.
Ngày 4: Decorator & Context Manager
Mục tiêu: Hiểu 2 pattern xuất hiện khắp nơi trong PyTorch (
@torch.no_grad(),with torch.autocast()).Lý thuyết: Function decorator, decorator có tham số, class-based decorator; context manager qua
__enter__/__exit__vàcontextlib.contextmanager.Thực hành: Tự viết decorator
@timeit,@retry(n); tự viết context managerno_grad_mock()mô phỏng logic bật/tắt một global flag giống cáchtorch.no_grad()hoạt động.
Ngày 5: Generator & Iterator
Mục tiêu: Nắm vững nền tảng để tự viết DataLoader hiệu quả bộ nhớ.
Lý thuyết: Iterator protocol (
__iter__,__next__), generator function (yield), generator expression, lazy evaluation,itertools.Thực hành: Viết DataLoader đơn giản bằng generator đọc file lớn theo batch mà không load hết vào RAM; benchmark memory usage so với cách load toàn bộ vào list.
Ngày 6: Asyncio
Mục tiêu: Hiểu concurrency bất đồng bộ, dùng được cho I/O trong data pipeline hoặc serving sau này.
Lý thuyết: Event loop,
async/await, coroutine,asyncio.gather, khác biệt với threading/multiprocessing.Thực hành: Viết script async tải song song nhiều file/URL, so sánh thời gian với cách tải tuần tự.
Ngày 7: Multiprocessing vs Threading
Mục tiêu: Biết chọn đúng công cụ cho data loading pipeline (GIL, CPU-bound vs I/O-bound).
Lý thuyết: GIL là gì và ảnh hưởng thế nào;
multiprocessing(process pool, shared memory) vsthreading(thread pool); khi nào dùng cái nào.Thực hành: Viết cùng một tác vụ tiền xử lý ảnh (CPU-bound) bằng cả threading và multiprocessing, benchmark thời gian chạy, giải thích kết quả bằng lý thuyết GIL.
Ngày 8: Memory Management & Type Hinting
Mục tiêu: Viết code Python "production-grade", dễ đọc, ít leak.
Lý thuyết: Reference counting, garbage collector, circular reference,
weakref; type hinting nâng cao (Generic,Protocol,TypeVar).Thực hành: Hoàn thiện lại DataLoader ở Ngày 5 với type hint đầy đủ + kiểm tra bằng
mypy; viết multiprocessing pipeline hoàn chỉnh (worker đọc file → queue → main process xử lý) làm project tổng hợp cho tuần Python.
Ngày 9: C++ cơ bản (Phần 1)
Mục tiêu: Bắt đầu xây nền C++ để chuẩn bị đọc source code PyTorch (Giai đoạn 7).
Lý thuyết: Cú pháp cơ bản, kiểu dữ liệu, con trỏ (pointer) vs tham chiếu (reference), stack vs heap, biên dịch với g++/CMake cơ bản.
Thực hành: Viết vài chương trình C++ nhỏ: quản lý mảng động bằng con trỏ, cấp phát/giải phóng thủ công (
new/delete), quan sát lỗi memory leak khi quêndelete.
Ngày 10: C++ cơ bản (Phần 2) - hướng tới đọc ATen
Mục tiêu: Đủ vốn C++ để không "sợ" khi mở source PyTorch.
Lý thuyết: Class trong C++, constructor/destructor, RAII (Resource Acquisition Is Initialization), smart pointer (
unique_ptr,shared_ptr), template cơ bản, namespace.Thực hành: Viết một class
Tensortối giản bằng C++ dùngshared_ptrđể quản lý buffer dữ liệu (mô phỏng ý tưởngStorage/TensorImplmà bạn sẽ gặp lại ở Giai đoạn 7).
Ngày 11: NumPy
Mục tiêu: Hiểu NumPy ở mức đủ sâu để giải thích được vì sao một số thao tác nhanh/chậm.
Lý thuyết:
ndarraylà gì, stride, contiguous memory, broadcasting rules, view vs copy, vectorization và tại sao nó nhanh hơn vòng lặp Python.Thực hành: Viết lại 3-4 hàm NumPy phổ biến (sum theo axis, transpose, reshape) bằng vòng lặp Python thuần rồi benchmark so với bản NumPy để cảm nhận tốc độ; kiểm tra
.flags,.stridescủa array sau các thao tác slicing/transpose.
Ngày 12: Linear Algebra cho Deep Learning
Mục tiêu: Có nền toán chắc cho backpropagation và các kiến trúc sau này.
Lý thuyết: Vector space, ma trận và các phép biến đổi tuyến tính, eigenvalue/eigenvector, SVD (Singular Value Decomposition), ứng dụng SVD trong PCA.
Thực hành: Cài đặt PCA từ đầu bằng NumPy (dùng eigendecomposition hoặc SVD) trên một tập dữ liệu nhỏ, trực quan hoá kết quả giảm chiều.
Ngày 13: Calculus cho Deep Learning
Mục tiêu: Hiểu cơ chế toán học đằng sau backpropagation trước khi cài đặt nó ở Giai đoạn 1.
Lý thuyết: Đạo hàm, đạo hàm riêng, chain rule (quy tắc chuỗi) - nền tảng của backprop, Jacobian, Hessian, ý nghĩa hình học của gradient.
Thực hành: Tính tay đạo hàm của vài hàm hợp đơn giản (vd
f(x) = sigmoid(Wx + b)), sau đó verify bằng numerical gradient checking (finite difference) viết bằng NumPy.
Ngày 14: Probability & Optimization Theory
Mục tiêu: Hiểu vì sao Cross Entropy là loss chuẩn cho classification, và cơ chế các optimizer phổ biến.
Lý thuyết: Bayes' theorem, MLE vs MAP, Entropy, Cross Entropy, KL Divergence (liên hệ với Cross Entropy loss); Gradient Descent, Momentum, RMSProp, Adam, khái niệm L-BFGS.
Thực hành: Chứng minh (trên giấy) rằng minimize Cross Entropy tương đương MLE cho phân phối categorical; viết bằng NumPy 3 optimizer (SGD, Momentum, Adam) áp dụng lên một hàm loss toy 2D, vẽ đường hội tụ để so sánh.
Ngày 15: Project tổng hợp Giai đoạn 0
Mục tiêu: Kiểm tra lại toàn bộ kiến thức nền bằng một project thực chiến, sẵn sàng cho Giai đoạn 1.
Lý thuyết: Ôn tập nhanh toàn bộ 14 ngày - liệt kê lại các khái niệm cốt lõi cần nhớ (stride, chain rule, GIL, RAII, SVD...).
Thực hành: Tự cài đặt chỉ bằng NumPy thuần:
Linear Layer,Conv2D(forward only),MaxPool,BatchNorm(forward only) - đúng như đề bài gốc của bạn. Viết unit test bằng pytest cho từng layer, so sánh output với PyTorch (dùng làm oracle) để tự chấm điểm độ chính xác cài đặt.
Checkpoint cuối Giai đoạn 0
Trước khi sang Giai đoạn 1, tự hỏi:
Tôi có thể giải thích chain rule bằng lời cho người không biết toán không?
Tôi có thể đọc một đoạn code C++ có
shared_ptrmà không hoảng không?DataLoader bằng generator của tôi có xử lý được file > RAM không?
4 layer NumPy thuần ở Ngày 15 có khớp output với PyTorch trong sai số 1e-5 không?
Nếu còn "không" ở câu nào, dành thêm 2-3 ngày ôn trước khi tiếp tục.
Giai Đoạn 1 - Deep Learning Fundamentals (Ngày 16 - 40)
Mục tiêu giai đoạn: Tự cài đặt toàn bộ một mạng neural network - forward, backward, loss, optimizer, regularization - chỉ bằng NumPy, không dùng bất kỳ framework nào, để hiểu tận gốc trước khi chạm vào PyTorch/TensorFlow ở Giai đoạn 2-3.
Ngày 16: Forward Pass - từ neuron đơn tới layer
Mục tiêu: Hiểu một layer neural network thực chất là phép biến đổi toán học nào.
Lý thuyết: Mô hình một neuron (
z = w·x + b,a = f(z)), mở rộng thành layer bằng phép nhân ma trận (Z = XW + b), tại sao dùng ma trận thay vì vòng lặp.Thực hành: Cài đặt forward pass của 1 layer bằng NumPy thuần, verify shape của input/output/weight qua nhiều cấu hình batch size khác nhau.
Ngày 17: Backpropagation
Mục tiêu: Tự dẫn ra công thức backprop thay vì học thuộc.
Lý thuyết: Áp dụng chain rule (đã học Ngày 13) để tính
dL/dW,dL/db,dL/dXcho một layer Linear + activation; khái niệm "gradient chảy ngược" qua computation graph.Thực hành: Dẫn tay trên giấy công thức backprop cho mạng 2 layer, chụp ảnh lưu lại làm tài liệu tham chiếu cho các ngày sau.
Ngày 18: Cài đặt Backprop cho MLP 2 lớp
Mục tiêu: Biến công thức Ngày 17 thành code chạy được.
Lý thuyết: Cấu trúc code: forward lưu lại activation trung gian (cache) để dùng cho backward; thứ tự tính gradient ngược từ output về input.
Thực hành: Cài đặt class
MLP2Layerbằng NumPy vớiforward()vàbackward(), kiểm tra gradient bằng numerical gradient checking (finite difference) - sai số phải < 1e-6.
Ngày 19: Gradient Descent
Mục tiêu: Hiểu sự khác biệt full-batch/mini-batch/stochastic ảnh hưởng thế nào tới hội tụ.
Lý thuyết: Full-batch GD, Stochastic GD (SGD đơn mẫu), Mini-batch GD; đánh đổi giữa tốc độ hội tụ, nhiễu gradient và chi phí tính toán.
Thực hành: Chạy cùng bài toán trên cả 3 chế độ, vẽ đường loss theo iteration để so sánh độ "gồ ghề" của đường hội tụ.
Ngày 20: Project - Linear Regression từ đầu
Mục tiêu: Hoàn thiện end-to-end pipeline training đầu tiên.
Lý thuyết: MSE loss và đạo hàm của nó, closed-form solution (Normal Equation) để đối chiếu với nghiệm bằng GD.
Thực hành: Cài Linear Regression bằng NumPy thuần (forward + backward + train loop), so sánh nghiệm học được bằng GD với nghiệm closed-form trên cùng dataset.
Ngày 21: Project - Logistic Regression từ đầu
Mục tiêu: Chuyển từ regression sang classification, làm quen BCE loss.
Lý thuyết: Sigmoid + Binary Cross Entropy, decision boundary tuyến tính, vì sao MSE không phù hợp cho classification (vanishing gradient khi kết hợp sigmoid).
Thực hành: Cài Logistic Regression từ đầu, train trên dataset nhị phân, vẽ decision boundary.
Ngày 22: Project - MLP hoàn chỉnh đa lớp, đa class
Mục tiêu: Tổng hợp Ngày 16-21 thành một mạng thực chiến.
Lý thuyết: Softmax + Categorical Cross Entropy cho multi-class, backprop qua nhiều layer ẩn.
Thực hành: Cài MLP N-layer cấu hình được (số layer, số neuron truyền vào constructor) bằng NumPy, train trên dataset toy multi-class (vd Iris hoặc synthetic blobs), đạt accuracy hợp lý.
Ngày 23: Activation Functions (1) - Sigmoid & Tanh
Mục tiêu: Hiểu vấn đề saturation của các activation cổ điển.
Lý thuyết: Công thức và đạo hàm Sigmoid, Tanh; hiện tượng saturation (gradient ≈ 0 ở hai đầu), vanishing gradient khi stack nhiều layer.
Thực hành: Vẽ đồ thị hàm và đạo hàm của cả hai; thực nghiệm train mạng sâu (5-6 layer) dùng Sigmoid, quan sát gradient ở layer đầu gần như biến mất (in ra norm của gradient từng layer).
Ngày 24: Activation Functions (2) - ReLU & Leaky ReLU
Mục tiêu: Hiểu vì sao ReLU trở thành mặc định, và vấn đề "dead neuron".
Lý thuyết: Công thức ReLU, đạo hàm (không liên tục tại 0), hiện tượng dead neuron (neuron luôn output 0, gradient luôn 0, không bao giờ học lại được); Leaky ReLU giải quyết vấn đề này thế nào.
Thực hành: Thực nghiệm gây dead neuron bằng learning rate quá cao + ReLU, quan sát % neuron "chết" theo epoch; so sánh với Leaky ReLU trong cùng điều kiện.
Ngày 25: Activation Functions (3) - GELU & Swish
Mục tiêu: Làm quen các activation hiện đại dùng trong Transformer (sẽ gặp lại ở Giai đoạn 6).
Lý thuyết: Công thức GELU (xấp xỉ bằng tanh), Swish (
x·sigmoid(βx)), vì sao chúng mượt hơn ReLU và hoạt động tốt hơn trong mạng rất sâu/Transformer.Thực hành: Cài đặt GELU và Swish bằng NumPy (cả forward và backward), so sánh hình dạng đồ thị với ReLU/Leaky ReLU trên cùng một hình.
Ngày 26: Loss Functions (1) - MSE & MAE
Mục tiêu: Biết chọn loss phù hợp với bài toán regression.
Lý thuyết: Công thức và đạo hàm MSE, MAE; độ nhạy với outlier (MSE phạt nặng outlier hơn MAE), Huber Loss như một điểm cân bằng.
Thực hành: Cài cả 3 loss bằng NumPy, thực nghiệm trên dataset có outlier để thấy MSE bị outlier "kéo" nghiệm nhiều hơn MAE.
Ngày 27: Loss Functions (2) - BCE & Cross Entropy
Mục tiêu: Nắm chắc loss quan trọng nhất cho classification, dẫn xuất gradient kết hợp với Softmax.
Lý thuyết: Dẫn công thức đạo hàm của
Softmax + CrossEntropykết hợp (kết quả đơn giản đến bất ngờ:y_pred - y_true) - đây là kiến thức nền tảng sẽ gặp lại khi đọc source code framework.Thực hành: Cài đặt Softmax + CrossEntropy bằng 2 cách (tách riêng vs kết hợp), verify gradient bằng numerical checking, so sánh độ ổn định số học (numerical stability) - chú ý kỹ thuật
log-sum-expđể tránh overflow.
Ngày 28: Loss Functions (3) - Focal Loss
Mục tiêu: Hiểu loss xử lý class imbalance, thường gặp trong Detection (sẽ gặp lại ở Giai đoạn 4).
Lý thuyết: Công thức Focal Loss (
-(1-p)^γ log(p)), ý tưởng giảm trọng số cho các mẫu đã dễ phân loại đúng, tập trung vào mẫu khó.Thực hành: Cài Focal Loss bằng NumPy, thực nghiệm trên dataset mất cân bằng nặng (vd 95%/5%), so sánh performance với CrossEntropy thường.
Ngày 29: Optimizer - SGD & Momentum
Mục tiêu: Hiểu vì sao thêm "quán tính" giúp hội tụ nhanh và ổn định hơn.
Lý thuyết: Công thức SGD thuần, Momentum (
v = βv + ∇L,θ = θ - αv), trực giác vật lý (quả bóng lăn xuống dốc), giúp vượt qua local minima nông và giảm dao động (oscillation) trên bề mặt loss hẹp.Thực hành: Cài SGD và Momentum bằng NumPy, thực nghiệm trên hàm loss dạng "thung lũng hẹp" (vd Rosenbrock function), quan sát Momentum hội tụ nhanh hơn rõ rệt.
Ngày 30: Optimizer - Adam
Mục tiêu: Hiểu optimizer phổ biến nhất hiện nay hoạt động thế nào bên trong.
Lý thuyết: Adam kết hợp Momentum (moment bậc 1) và RMSProp (moment bậc 2, adaptive learning rate per-parameter); bias correction ở các bước đầu và tại sao nó cần thiết.
Thực hành: Cài Adam từ đầu bằng NumPy (đầy đủ bias correction), so sánh đường hội tụ với SGD/Momentum trên cùng bài toán.
Ngày 31: Optimizer - AdamW
Mục tiêu: Hiểu sự khác biệt tinh tế nhưng quan trọng giữa Adam+L2 và AdamW - kiến thức sẽ dùng lại khi train LLM ở Giai đoạn 6.
Lý thuyết: Vấn đề khi kết hợp L2 regularization trực tiếp vào gradient trong Adam (bị "pha loãng" bởi adaptive learning rate); AdamW decouple weight decay ra khỏi bước gradient.
Thực hành: Cài AdamW từ đầu, thực nghiệm so sánh Adam+L2 vs AdamW trên cùng mạng, quan sát sự khác biệt về hiệu quả regularization.
Ngày 32: Regularization - Dropout
Mục tiêu: Hiểu và cài đặt kỹ thuật regularization phổ biến nhất.
Lý thuyết: Cơ chế Dropout (random mask neuron khi train), inverted dropout (scale ở train để không cần scale ở test), vì sao nó hoạt động như một dạng ensemble ngầm.
Thực hành: Cài Dropout layer (forward + backward) bằng NumPy, train MLP Ngày 22 với và không có Dropout trên dataset dễ overfit, so sánh gap giữa train/val accuracy.
Ngày 33: Regularization - Weight Decay & Label Smoothing
Mục tiêu: Thêm 2 công cụ chống overfitting phổ biến vào bộ công cụ.
Lý thuyết: Weight Decay như một dạng L2 penalty lên trọng số; Label Smoothing làm "mềm" target one-hot để tránh mô hình quá tự tin (overconfident).
Thực hành: Cài cả hai kỹ thuật, thực nghiệm đo độ tự tin (confidence) của model trước/sau khi áp dụng Label Smoothing trên tập test.
Ngày 34: Regularization - Early Stopping & Validation Strategy
Mục tiêu: Xây quy trình train/validate đúng chuẩn, tránh data leakage.
Lý thuyết: Train/Validation/Test split, early stopping dựa trên validation loss, patience, và vì sao không nên "nhìn" test set trong lúc train.
Thực hành: Viết training loop có early stopping tự động (lưu checkpoint tốt nhất theo val loss), áp dụng lên MLP Ngày 22.
Ngày 35: Weight Initialization
Mục tiêu: Hiểu vì sao khởi tạo trọng số sai có thể khiến mạng không học được gì.
Lý thuyết: Vấn đề nếu khởi tạo toàn 0 hoặc quá lớn/quá nhỏ; Xavier/Glorot initialization (cho Sigmoid/Tanh), He initialization (cho ReLU) - công thức và lý do đằng sau (giữ variance activation ổn định qua các layer).
Thực hành: Thực nghiệm khởi tạo mạng 10 layer với 3 cách (zero, random lớn, He init đúng chuẩn), in ra variance của activation ở từng layer để thấy rõ sự khác biệt.
Ngày 36: Batch Training Mechanics
Mục tiêu: Hiểu rõ các khái niệm hay bị nhầm: epoch, iteration, batch size.
Lý thuyết: 1 epoch = duyệt hết dataset; 1 iteration = 1 lần update trên 1 batch; ảnh hưởng của batch size lên tốc độ train, độ nhiễu gradient, và khả năng generalize (batch nhỏ thường generalize tốt hơn).
Thực hành: Viết lại training loop chuẩn có shuffle dữ liệu mỗi epoch, thử nghiệm với batch size 8/32/128/512, ghi lại thời gian/epoch và accuracy cuối cùng để so sánh.
Ngày 37: Debug Training - Overfitting vs Underfitting
Mục tiêu: Biết "đọc" learning curve để chẩn đoán vấn đề của mô hình - kỹ năng sẽ dùng suốt các giai đoạn sau.
Lý thuyết: Learning curve điển hình của underfitting (train loss cao, không giảm), overfitting (train loss thấp nhưng val loss tăng), và "good fit"; bias-variance tradeoff.
Thực hành: Cố tình tạo ra 3 kịch bản (model quá đơn giản, model quá phức tạp không regularize, model cân bằng), vẽ learning curve của cả 3 và viết nhận xét chẩn đoán cho từng trường hợp.
Ngày 38: Project - Xây "Mini Deep Learning Framework"
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 1 thành một framework nhỏ có kiến trúc giống PyTorch (chuẩn bị tư duy cho Giai đoạn 2).
Lý thuyết: Kiến trúc module hoá: base class
Layer(cóforward/backward),Loss,Optimizertách rời,Sequentialcontainer để nối các layer.Thực hành: Refactor toàn bộ code từ Ngày 16-37 thành framework với API dạng:
model = Sequential([Linear(...), ReLU(), Linear(...)]),optimizer = Adam(model.parameters()),loss = CrossEntropy().
Ngày 39: Train Mini Framework trên MNIST (NumPy thuần)
Mục tiêu: Chứng minh framework tự viết hoạt động trên dữ liệu thực, không chỉ toy data.
Lý thuyết: Ôn lại toàn bộ pipeline: load data → normalize → forward → loss → backward → optimizer step → validate.
Thực hành: Dùng framework Ngày 38 train trên MNIST (load bằng NumPy, không dùng torchvision), đạt tối thiểu ~95% accuracy trên test set, đo thời gian train và so sánh sơ bộ với việc dùng PyTorch (chỉ để cảm nhận, chưa cần tối ưu).
Ngày 40: Checkpoint & Review Giai đoạn 1
Mục tiêu: Củng cố kiến thức trước khi chuyển sang PyTorch Core.
Lý thuyết: Tự tổng hợp lại (viết note hoặc thuyết trình cho chính mình) toàn bộ chuỗi: forward → backward → loss → optimizer → regularization, chỉ ra mối liên hệ giữa các phần.
Thực hành: Làm bài test tự đánh giá: (1) dẫn tay backprop cho 1 layer bất kỳ không nhìn tài liệu, (2) cài đặt Adam từ trí nhớ, (3) giải thích vì sao AdamW khác Adam trong 3 câu. Nếu cả 3 đều làm được → sẵn sàng cho Giai đoạn 2.
Checkpoint cuối Giai đoạn 1
Framework NumPy tự viết có đạt ≥95% trên MNIST không?
Có thể dẫn công thức Softmax+CrossEntropy gradient (
y_pred - y_true) mà không cần tra cứu không?Có thể giải thích sự khác biệt Adam vs AdamW cho người khác hiểu không?
Có thể đọc một learning curve và chẩn đoán overfit/underfit trong vài giây không?
Nếu còn "không", dành 2-3 ngày ôn lại phần tương ứng trước khi bước sang Giai đoạn 2 - PyTorch Core.
Giai Đoạn 2 - PyTorch Core (Ngày 41 - 75)
Mục tiêu giai đoạn: Hiểu PyTorch ở mức đủ sâu để tự cài lại các thành phần lõi (Tensor, Autograd, nn.Module, DataLoader, training loop) thay vì chỉ gọi API.
Ngày 41: Tensor Fundamentals - Tạo & dtype
Mục tiêu: Nắm chắc cách tạo và khai báo kiểu dữ liệu Tensor.
Lý thuyết: Các cách tạo tensor (
torch.tensor,zeros,randn,from_numpy), các dtype phổ biến (float32, float16, bfloat16, int64) và khi nào dùng loại nào.Thực hành: Viết script tạo tensor bằng mọi cách, thử ép kiểu qua lại, quan sát lỗi khi cộng 2 tensor khác dtype.
Ngày 42: Tensor Operations & Broadcasting
Mục tiêu: Thành thạo thao tác tensor như NumPy nhưng hiểu thêm phần autograd-aware.
Lý thuyết: Indexing/slicing, broadcasting rules (giống NumPy), in-place ops (
add_) và rủi ro với autograd.Thực hành: Viết loạt bài tập broadcasting phức tạp (3-4 chiều), thử in-place op trên tensor có
requires_grad=Trueđể thấy lỗi autograd xảy ra.
Ngày 43: view/reshape/permute/contiguous
Mục tiêu: Hiểu bản chất memory layout đằng sau các hàm hay gây lỗi nhất cho người mới.
Lý thuyết: Stride và memory layout (liên hệ NumPy đã học); khác biệt
view()(yêu cầu contiguous) vsreshape()(tự copy nếu cần) vspermute()(đổi stride, không đổi data).Thực hành: Tạo tensor, permute rồi thử
view()để tái hiện lỗi "not contiguous", sửa bằng.contiguous(), in.stride()trước/sau mỗi thao tác để quan sát.
Ngày 44: Device Management & CPU↔GPU
Mục tiêu: Quản lý tensor giữa CPU/GPU hiệu quả, tránh bottleneck.
Lý thuyết:
.to(device),.cuda(), pinned memory (pin_memory=True) giúp transfer nhanh hơn, đồng bộ CPU-GPU (torch.cuda.synchronize()).Thực hành: Benchmark transfer tensor lớn giữa CPU/GPU có và không có pinned memory, đo thời gian bằng CUDA events.
Ngày 45: Autograd - Computation Graph
Mục tiêu: Hiểu cơ chế nền của autograd trước khi tự cài.
Lý thuyết:
requires_grad,grad_fn, leaf tensor vs non-leaf, computation graph được xây dựng động trong lúc forward.Thực hành: Xây một biểu thức phức hợp, in
.grad_fncủa từng bước, vẽ tay computation graph tương ứng.
Ngày 46: Dynamic Graph vs Static Graph
Mục tiêu: Hiểu khác biệt triết lý giữa PyTorch (define-by-run) và TensorFlow 1.x (define-and-run) - chuẩn bị cho Giai đoạn 3.
Lý thuyết: Ưu/nhược điểm dynamic graph (dễ debug, linh hoạt với control flow) vs static graph (tối ưu tốt hơn, cần biết trước shape).
Thực hành: Viết một mô hình có
if/elsephụ thuộc vào input (control flow động), thử hình dung việc này khó thế nào nếu phải định nghĩa graph tĩnh trước.
Ngày 47: backward() Mechanics
Mục tiêu: Hiểu rõ điều gì xảy ra khi gọi
.backward().Lý thuyết: Reverse-mode automatic differentiation,
retain_graph, vì sao gọibackward()2 lần trên cùng graph mặc định sẽ lỗi.Thực hành: Thử gọi
backward()nhiều lần với và không córetain_graph=True, giải thích lỗi gặp phải.
Ngày 48: Gradient Accumulation
Mục tiêu: Hiểu kỹ thuật mô phỏng batch size lớn khi GPU không đủ VRAM - sẽ dùng lại khi train LLM ở Giai đoạn 6.
Lý thuyết: Gradient tự cộng dồn qua nhiều lần
backward()nếu khôngzero_grad(); tận dụng đặc tính này để accumulate qua N mini-batch trước khioptimizer.step().Thực hành: Viết training loop với gradient accumulation (effective batch size = batch_size × N), verify loss tương đương với batch size lớn thật.
Ngày 49: Mini-Autograd Engine - Thiết kế
Mục tiêu: Bắt đầu project quan trọng nhất giai đoạn: tự viết autograd engine giống
micrograd.Lý thuyết: Thiết kế class
Valuebọc một số thực, lưugrad,_prev(các node cha),_backward(hàm tính gradient cục bộ).Thực hành: Cài class
Valuevới các phép+,*, khởi tạo graph khi thực hiện phép toán.
Ngày 50: Mini-Autograd Engine - Mở rộng toán tử
Mục tiêu: Mở rộng engine để đủ dùng cho một MLP.
Lý thuyết: Cách mỗi toán tử (
pow,exp,relu,tanh) tự định nghĩa local gradient của nó trong_backward.Thực hành: Thêm các toán tử còn thiếu vào class
Value, viết unit test so gradient với đạo hàm giải tích tay.
Ngày 51: Mini-Autograd Engine - Topological Sort & backward()
Mục tiêu: Hoàn thiện cơ chế lan truyền ngược tự động.
Lý thuyết: Thuật toán topological sort trên computation graph để đảm bảo thứ tự gọi
_backwardđúng (từ output về input).Thực hành: Cài
backward()cho classValuedùng topological sort, test trên biểu thức nhiều bước.
Ngày 52: Mini-Autograd Engine - Build MLP & So sánh với PyTorch
Mục tiêu: Hoàn thiện engine, verify đúng đắn bằng cách đối chiếu với PyTorch thật.
Lý thuyết: Ôn lại cách nn.Module quản lý parameters để mô phỏng tương tự với engine tự viết.
Thực hành: Dùng engine tự viết xây MLP nhỏ, train trên bài toán toy, so sánh gradient và kết quả train với PyTorch trên cùng bài toán, cùng seed.
Ngày 53: nn.Module Anatomy
Mục tiêu: Hiểu cấu trúc bên trong
nn.Module.Lý thuyết:
__init__,forward, cáchparameters()tự động thu thập tham số qua__setattr__override,state_dict().Thực hành: Viết class
MyModuletối giản mô phỏng cáchnn.Moduletự động đăng ký sub-module và parameter khi gán bằngself.x = ....
Ngày 54: Parameters vs Buffers
Mục tiêu: Phân biệt rõ 2 khái niệm hay bị nhầm.
Lý thuyết:
nn.Parameter(có gradient, được optimizer cập nhật) vs buffer (register_buffer, không có gradient nhưng vẫn lưu trongstate_dict, vd running_mean của BatchNorm).Thực hành: Viết custom module có cả parameter và buffer, verify buffer không xuất hiện trong
model.parameters()nhưng có trongstate_dict().
Ngày 55: Hooks
Mục tiêu: Biết dùng hook để debug/can thiệp vào forward và backward mà không sửa code model.
Lý thuyết:
register_forward_hook,register_backward_hook(vàregister_full_backward_hook), use case: trích xuất feature trung gian, kiểm tra gradient theo layer.Thực hành: Gắn forward hook để lấy activation của một layer ẩn trong mạng có sẵn; gắn backward hook để in norm gradient từng layer, phát hiện layer nào gradient gần 0.
Ngày 56: Implement nn.Linear từ đầu
Mục tiêu: Tự cài lại layer cơ bản nhất bằng autograd thật của PyTorch (không phải mini-engine).
Lý thuyết: Cách
nn.Linearkhởi tạo weight/bias, forward là phép nhân ma trận.Thực hành: Viết class
MyLinear(nn.Module)kế thừa đúng chuẩn, so sánh output/gradient vớinn.Lineargốc trên cùng input, cùng trọng số khởi tạo.
Ngày 57: Implement nn.Conv2d từ đầu
Mục tiêu: Hiểu convolution cài đặt thế nào ở mức tensor operation (chuẩn bị sâu hơn ở Giai đoạn 4).
Lý thuyết: Cách convolution có thể biểu diễn qua
unfold(im2col) + phép nhân ma trận.Thực hành: Cài
MyConv2ddùng kỹ thuật im2col, so sánh output vớinn.Conv2dgốc, benchmark tốc độ (nhận ra vì sao cần cuDNN sau này).
Ngày 58: Implement BatchNorm từ đầu
Mục tiêu: Hiểu khác biệt hành vi train/eval - nguồn lỗi phổ biến nhất khi debug model.
Lý thuyết: Công thức BatchNorm, running_mean/running_var cập nhật bằng momentum trong lúc train, dùng running stats (không phải batch stats) khi eval.
Thực hành: Cài
MyBatchNorm, cố tình quên gọimodel.eval()khi test để tái hiện bug kinh điển, so sánh kết quả đúng/sai.
Ngày 59: Implement LayerNorm từ đầu
Mục tiêu: Phân biệt rõ BatchNorm vs LayerNorm - LayerNorm sẽ là chuẩn trong Transformer ở Giai đoạn 6.
Lý thuyết: LayerNorm chuẩn hoá theo chiều feature (không phụ thuộc batch), vì sao phù hợp hơn cho NLP/Transformer so với BatchNorm.
Thực hành: Cài
MyLayerNorm, so sánh vớinn.LayerNorm, thử nghiệm với batch size = 1 để thấy BatchNorm gãy còn LayerNorm vẫn ổn.
Ngày 60: Dataset - Map-style vs Iterable-style
Mục tiêu: Biết chọn kiểu Dataset phù hợp cho từng tình huống dữ liệu.
Lý thuyết: Map-style Dataset (
__getitem__,__len__) vs IterableDataset (__iter__) - khi nào dùng iterable (streaming data, dataset không biết trước độ dài).Thực hành: Viết cả 2 loại Dataset cho cùng một nguồn dữ liệu, so sánh cách DataLoader xử lý chúng khác nhau.
Ngày 61: DataLoader
Mục tiêu: Hiểu cơ chế song song hoá đằng sau DataLoader.
Lý thuyết:
collate_fn(gộp list sample thành batch),num_workers(multiprocessing để load song song),pin_memory,prefetch_factor.Thực hành: Viết
collate_fntuỳ chỉnh cho dữ liệu có độ dài khác nhau (padding); benchmark thời gian load vớinum_workers=0/2/8.
Ngày 62: Sampler
Mục tiêu: Kiểm soát thứ tự/tỉ lệ lấy mẫu trong mỗi epoch.
Lý thuyết:
RandomSampler,SequentialSampler,WeightedRandomSampler(xử lý class imbalance bằng cách lấy mẫu có trọng số).Thực hành: Viết custom Sampler xử lý dataset mất cân bằng, verify tỉ lệ class trong mỗi batch được cân bằng hơn.
Ngày 63: DistributedSampler - Nhập môn
Mục tiêu: Làm quen khái niệm sẽ dùng đầy đủ ở Giai đoạn 9 (multi-GPU training).
Lý thuyết: Vì sao cần chia dữ liệu không trùng lặp giữa các process khi train phân tán;
set_epoch()để đảm bảo shuffle khác nhau mỗi epoch.Thực hành: Đọc source code
DistributedSampler, viết giả lập (mock) 2 "worker" trên 1 máy để verify dữ liệu không bị trùng giữa 2 worker.
Ngày 64: Dataset >100GB - Lazy Loading & Sharding
Mục tiêu: Biết xử lý dữ liệu lớn hơn RAM.
Lý thuyết: Memory-mapped file (
np.memmap), lazy loading (chỉ đọc khi cần trong__getitem__), sharding dữ liệu thành nhiều file nhỏ (webdataset-style).Thực hành: Tạo dataset giả lớn (ghi nhiều file .npy), viết Dataset dùng memmap để đọc mà không load hết vào RAM, verify RAM usage ổn định khi dataset lớn hơn RAM máy.
Ngày 65: Data Augmentation Pipeline
Mục tiêu: Xây pipeline augmentation hiệu quả, không làm nghẽn GPU.
Lý thuyết: Augmentation nên chạy trên CPU (trong
__getitem__/num_workers) song song với GPU đang tính toán batch trước;torchvision.transformscơ chế compose.Thực hành: Viết pipeline augmentation tuỳ chỉnh (không chỉ dùng transform có sẵn - viết 1 augmentation riêng), benchmark GPU utilization trước/sau khi tăng
num_workers.
Ngày 66: Viết train() Loop Skeleton
Mục tiêu: Có khung training loop chuẩn, tái sử dụng được cho mọi project sau này.
Lý thuyết: Thứ tự chuẩn:
optimizer.zero_grad()→forward→loss.backward()→optimizer.step(); vị trí đặtmodel.train().Thực hành: Viết hàm
train_one_epoch()tổng quát, nhận model/dataloader/optimizer/loss_fn làm tham số, log loss theo iteration.
Ngày 67: Viết validate() Loop
Mục tiêu: Đảm bảo đánh giá model đúng cách, không lãng phí bộ nhớ.
Lý thuyết:
model.eval()+torch.no_grad()(hoặctorch.inference_mode()), vì sao cần cả hai (eval đổi behavior của BatchNorm/Dropout, no_grad tắt autograd tiết kiệm bộ nhớ).Thực hành: Viết hàm
validate(), benchmark memory usage có/không cóno_grad().
Ngày 68: Checkpointing
Mục tiêu: Lưu và khôi phục model đúng chuẩn production.
Lý thuyết:
state_dict()của model và optimizer, vì sao nên lưu cả 2 (Adam có internal state cần khôi phục), format checkpoint (dict chứa epoch, model_state, optimizer_state, best_metric).Thực hành: Viết hàm
save_checkpoint()/load_checkpoint()đầy đủ, test bằng cách dừng training giữa chừng rồi load lại tiếp tục.
Ngày 69: Resume Training & Reproducibility
Mục tiêu: Đảm bảo resume training cho kết quả giống hệt như không bị gián đoạn.
Lý thuyết: Cần lưu thêm: epoch/step hiện tại, trạng thái LR scheduler, RNG state (
torch.get_rng_state) để đảm bảo reproducibility.Thực hành: Mở rộng checkpoint Ngày 68 để lưu đầy đủ RNG state, verify resume cho ra đúng loss như chạy liên tục không ngắt.
Ngày 70: Learning Rate Scheduler
Mục tiêu: Hiểu và áp dụng các chiến lược điều chỉnh LR phổ biến.
Lý thuyết:
StepLR,CosineAnnealingLR, warmup (đặc biệt quan trọng khi train mạng sâu/Transformer sau này) - vì sao warmup giúp tránh instability ở những step đầu.Thực hành: Cài đặt warmup + cosine decay thủ công (không dùng scheduler có sẵn), vẽ đường LR theo step để verify đúng hình dạng mong muốn.
Ngày 71: Gradient Clipping
Mục tiêu: Biết cách ngăn gradient explosion - vấn đề sẽ gặp nhiều khi train RNN/Transformer.
Lý thuyết: Norm-based clipping (
clip_grad_norm_) vs value-based clipping (clip_grad_value_), khi nào cần dùng.Thực hành: Cố tình gây gradient explosion (learning rate cao trên RNN đơn giản), áp dụng clipping để ổn định lại training.
Ngày 72: Mixed Precision - Nhập môn
Mục tiêu: Làm quen khái niệm sẽ đào sâu ở Giai đoạn 9.
Lý thuyết:
torch.autocast(tự động chọn FP16/BF16 cho op phù hợp),GradScaler(chống underflow gradient khi dùng FP16).Thực hành: Thêm autocast + GradScaler vào training loop Ngày 66, benchmark tốc độ train và VRAM sử dụng so với FP32 thuần trên cùng GPU.
Ngày 73: Logging & Experiment Tracking Cơ Bản
Mục tiêu: Xây thói quen log training có hệ thống trước khi học công cụ chuyên dụng (MLflow/W&B) ở Giai đoạn 10.
Lý thuyết: Những gì cần log tối thiểu (loss, lr, metric theo step/epoch), giới thiệu sơ lược TensorBoard.
Thực hành: Tích hợp
torch.utils.tensorboard.SummaryWritervào training loop, log loss/lr/gradient norm, mở TensorBoard xem trực quan.
Ngày 74: Project - Training Script Hoàn Chỉnh trên CIFAR-10
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 2 thành một script production-style.
Lý thuyết: Ôn lại toàn bộ pipeline: Dataset → DataLoader → Model (dùng layer tự cài Ngày 56-59) → train/validate → checkpoint/resume → scheduler → mixed precision → logging.
Thực hành: Viết 1 script hoàn chỉnh train CNN nhỏ (dùng
MyConv2d,MyBatchNormtự cài) trên CIFAR-10, có đầy đủ resume, mixed precision, TensorBoard logging, đạt accuracy hợp lý (~70-80%).
Ngày 75: Checkpoint & Review Giai đoạn 2
Mục tiêu: Củng cố trước khi chuyển sang TensorFlow Core.
Lý thuyết: Tổng hợp lại kiến trúc PyTorch: Tensor → Autograd → nn.Module → Data Pipeline → Training Loop, và cách chúng liên kết với nhau.
Thực hành: Tự kiểm tra: (1) cài lại
Valueclass autograd từ trí nhớ trong 30 phút, (2) giải thích khác biệt train/eval mode của BatchNorm cho người khác, (3) viết training loop chuẩn không nhìn tài liệu.
Checkpoint cuối Giai đoạn 2
Mini-autograd engine có cho gradient khớp với PyTorch thật không?
Layer tự cài (Linear/Conv2d/BatchNorm/LayerNorm) có khớp output với bản gốc không?
Script training CIFAR-10 có resume đúng và cho kết quả reproducible không?
Nếu ổn, tiếp tục sang Giai đoạn 3 - TensorFlow Core.
Giai Đoạn 3 - TensorFlow Core (Ngày 76 - 97)
Mục tiêu giai đoạn: Nắm chắc TensorFlow ở mức tương đương với PyTorch đã học, đặc biệt là những khác biệt triết lý (graph execution, tf.data, distributed strategy) để có thể so sánh và chọn công cụ phù hợp cho từng bài toán production.
Ngày 76: TensorFlow Tensor Fundamentals
Mục tiêu: Làm quen Tensor của TF, đối chiếu với PyTorch đã thành thạo.
Lý thuyết:
tf.Tensorimmutable (so vớitorch.Tensormutable),tf.Variablecho giá trị cần cập nhật (trọng số model), dtype và device placement trong TF.Thực hành: Viết bảng đối chiếu API TF ↔ PyTorch cho các thao tác cơ bản (tạo tensor, reshape, indexing), thử các thao tác đó trong TF.
Ngày 77: Eager Execution vs Graph Execution
Mục tiêu: Hiểu 2 chế độ thực thi của TF - nền tảng để hiểu
tf.functionở các ngày sau.Lý thuyết: Eager (chạy ngay từng op, giống PyTorch), Graph (biên dịch thành đồ thị tĩnh trước khi chạy, tối ưu hơn nhưng khó debug hơn); lịch sử TF1 (graph-only) → TF2 (eager mặc định).
Thực hành: Viết cùng một đoạn tính toán chạy ở chế độ eager, đo thời gian thực thi, quan sát khác biệt khi có breakpoint/print debug.
Ngày 78: tf.function - Tracing
Mục tiêu: Hiểu cơ chế biến code Python thành graph.
Lý thuyết: Khi decorate
@tf.function, TF "trace" hàm Python lần đầu để tạoConcreteFunction/graph; các lần gọi sau tái sử dụng graph nếu shape/dtype input không đổi.Thực hành: Thêm
print()bên trong hàm có@tf.function, gọi hàm nhiều lần với input cùng shape rồi khác shape, quan sát khi nàoprintchạy lại (dấu hiệu retracing).
Ngày 79: tf.function - Retracing Pitfalls
Mục tiêu: Tránh bẫy hiệu năng phổ biến nhất khi dùng
tf.function.Lý thuyết: Retracing tốn kém xảy ra khi truyền Python object thay vì tensor, hoặc shape thay đổi liên tục;
input_signatuređể ép cố định shape/dtype.Thực hành: Cố tình gây retracing liên tục (truyền số Python thường thay vì tensor), đo overhead, sửa bằng
input_signaturevà convert đúng sang tensor.
Ngày 80: tf.function - AutoGraph
Mục tiêu: Hiểu cách TF chuyển đổi control flow Python thành graph ops.
Lý thuyết: AutoGraph tự động chuyển
if/for/whiletrong Python thànhtf.cond/tf.while_loopkhi trace; giới hạn của AutoGraph (một số pattern Python phức tạp không convert được).Thực hành: Viết hàm có
ifphụ thuộc giá trị tensor, decorate@tf.function, dùngtf.autograph.to_code()để xem code graph tương đương được sinh ra.
Ngày 81: GradientTape - Autodiff trong TF
Mục tiêu: Hiểu cơ chế autograd của TF, so sánh với autograd PyTorch đã học ở Giai đoạn 2.
Lý thuyết:
tf.GradientTapeghi lại các phép toán trong context để tính gradient;watch()cho biến không phảitf.Variable; khác biệt so với computation graph tự động của PyTorch (TF cần khai báo tape tường minh).Thực hành: Tính gradient của một hàm nhiều biến bằng
GradientTape, so sánh kết quả với PyTorch autograd trên cùng hàm số.
Ngày 82: Keras Model - 3 API Styles
Mục tiêu: Biết chọn đúng API Keras cho từng mức độ phức tạp kiến trúc.
Lý thuyết: Sequential API (đơn giản, tuyến tính), Functional API (đồ thị có nhánh/multi-input/multi-output), Subclassing API (linh hoạt nhất, giống
nn.Modulecủa PyTorch).Thực hành: Xây cùng một kiến trúc nhỏ bằng cả 3 cách, nhận xét ưu/nhược điểm mỗi cách qua trải nghiệm thực tế.
Ngày 83: Keras Layer
Mục tiêu: Hiểu vòng đời một Layer trong Keras.
Lý thuyết:
__init__(cấu hình) vsbuild()(khởi tạo trọng số, biết shape input) vscall()(forward pass) - khác với PyTorch nơi mọi thứ khai báo trong__init__.Thực hành: Viết custom layer, in ra thứ tự gọi
__init__→build→callkhi model chạy lần đầu để quan sát lazy shape inference.
Ngày 84: Custom Layer - Dense từ đầu
Mục tiêu: Tự cài lại layer cơ bản nhất trong Keras.
Lý thuyết: Cách
build()tạo trọng số bằngadd_weight(), forward trongcall().Thực hành: Viết
MyDense(tf.keras.layers.Layer), so sánh output/gradient vớitf.keras.layers.Densegốc.
Ngày 85: Custom Layer - Conv2D từ đầu
Mục tiêu: Đối chiếu cách cài Conv2D trong TF với bản PyTorch đã cài ở Giai đoạn 2.
Lý thuyết:
tf.nn.conv2dlow-level API, formatNHWC(mặc định TF) vsNCHW(mặc định PyTorch) - điểm khác biệt hay gây lỗi khi chuyển đổi model giữa 2 framework.Thực hành: Viết
MyConv2Ddùngtf.nn.conv2d, so sánh output vớiConv2Dgốc, ghi chú lại sự khác biệt format NHWC/NCHW để tránh bug khi làm việc với ONNX sau này.
Ngày 86: Keras Callback System
Mục tiêu: Biết tận dụng callback thay vì viết logic thủ công trong training loop.
Lý thuyết: Vòng đời callback (
on_epoch_begin,on_batch_end,on_epoch_end...), các callback có sẵn:EarlyStopping,ModelCheckpoint,ReduceLROnPlateau.Thực hành: Viết custom callback tự log gradient norm mỗi epoch (tương tự hook đã làm ở PyTorch Ngày 55), gắn vào
model.fit().
Ngày 87: tf.data - Dataset Cơ Bản
Mục tiêu: Làm quen API xây data pipeline chuẩn của TF.
Lý thuyết:
tf.data.Dataset.from_tensor_slices,.map(),.batch(),.shuffle()- tư duy pipeline dạng "chain transformation" khác với Dataset/DataLoader tách rời của PyTorch.Thực hành: Xây pipeline đọc ảnh từ thư mục, áp dụng augmentation qua
.map(), batch lại, so sánh cú pháp vớiDataset/DataLoaderđã viết ở Giai đoạn 2.
Ngày 88: tf.data - Prefetch & Cache
Mục tiêu: Hiểu 2 kỹ thuật tối ưu I/O quan trọng nhất của tf.data.
Lý thuyết:
.prefetch(AUTOTUNE)chồng lấp thời gian chuẩn bị batch tiếp theo với thời gian train batch hiện tại (giống ý tưởngnum_workers+pin_memoryở PyTorch);.cache()lưu kết quả sau lần đọc/xử lý đầu để không lặp lại I/O.Thực hành: Benchmark pipeline có/không có
.prefetch(), đo GPU utilization; thử.cache()trên dataset vừa vặn RAM và quan sát tăng tốc epoch sau.
Ngày 89: tf.data - Parallel Map & Interleave
Mục tiêu: Tối ưu tốc độ xử lý dữ liệu song song.
Lý thuyết:
num_parallel_calls=AUTOTUNEtrong.map()để xử lý song song nhiều sample;.interleave()để đọc xen kẽ từ nhiều file nguồn song song (tương tự sharding đã học ở PyTorch Ngày 64).Thực hành: Benchmark
.map()vớinum_parallel_calls=1vsAUTOTUNE; xây pipeline đọc từ nhiều file TFRecord bằng.interleave().
Ngày 90: tf.data - Performance Tuning
Mục tiêu: Tổng hợp toàn bộ kỹ thuật thành một pipeline tối ưu hoàn chỉnh.
Lý thuyết: Thứ tự khuyến nghị các bước trong pipeline (
shuffle → map → batch → prefetch) và lý do;tf.data.experimental.AUTOTUNEtự động chọn tham số tối ưu.Thực hành: Xây pipeline tf.data tối ưu đầy đủ, dùng
tf.data.experimental.StatsOptionshoặc profiler để đo bottleneck ở từng bước.
Ngày 91: Custom Training Loop bằng GradientTape
Mục tiêu: Viết training loop thủ công trong TF, không phụ thuộc
model.fit()- tương đương train loop đã viết ở PyTorch Giai đoạn 2.Lý thuyết: Cấu trúc: mở
GradientTape→ forward → tính loss →tape.gradient()→optimizer.apply_gradients().Thực hành: Viết
train_step()vàtrain_one_epoch()bằng GradientTape thủ công, không dùng.fit(), verify kết quả giống với dùng.fit()trên cùng model/data.
Ngày 92: So sánh PyTorch vs TensorFlow Training Loop
Mục tiêu: Củng cố hiểu biết cả 2 framework qua so sánh trực tiếp.
Lý thuyết: Đối chiếu song song từng bước:
zero_grad()↔(TF không cần vì tape mới mỗi step),backward()↔tape.gradient(),optimizer.step()↔apply_gradients().Thực hành: Viết document (bảng) so sánh chi tiết API tương đương giữa 2 framework - tài liệu này sẽ hữu ích khi cần chuyển đổi giữa 2 hệ sinh thái trong công việc thực tế.
Ngày 93: MirroredStrategy
Mục tiêu: Bắt đầu làm quen distributed training trong TF.
Lý thuyết:
tf.distribute.MirroredStrategy- data parallelism trên nhiều GPU cùng máy, đồng bộ gradient bằng AllReduce (sẽ học sâu cơ chế NCCL ở Giai đoạn 9).Thực hành: Wrap model/optimizer trong
strategy.scope(), train trên máy multi-GPU (hoặc mô phỏng vớiCUDA_VISIBLE_DEVICESnếu chỉ có 1 GPU), so sánh throughput.
Ngày 94: MultiWorkerMirroredStrategy
Mục tiêu: Hiểu distributed training vượt ra ngoài 1 máy.
Lý thuyết: Cấu hình
TF_CONFIGđể các worker biết vai trò của nhau (chief/worker), cơ chế đồng bộ giữa các máy.Thực hành: Đọc kỹ tài liệu và (nếu có điều kiện) mô phỏng 2 process trên cùng máy đóng vai 2 worker khác nhau để hiểu luồng khởi tạo
TF_CONFIG.
Ngày 95: TPUStrategy - Tổng Quan
Mục tiêu: Biết TF có lợi thế riêng gì với phần cứng TPU của Google.
Lý thuyết: Kiến trúc TPU khác GPU ở điểm nào (systolic array),
tf.distribute.TPUStrategy, khi nào nên cân nhắc TPU thay vì GPU.Thực hành: Đọc benchmark so sánh TPU vs GPU cho một số model phổ biến, ghi chú lại các ràng buộc khi dùng TPU (yêu cầu static shape nghiêm ngặt hơn).
Ngày 96: Project - Tái Hiện CIFAR-10 Script bằng TensorFlow
Mục tiêu: Chứng minh có thể triển khai cùng một bài toán trên cả 2 framework thành thạo như nhau.
Lý thuyết: Ôn lại toàn bộ script PyTorch đã viết ở Ngày 74.
Thực hành: Viết lại chính xác bài toán đó bằng TensorFlow: custom layer (Dense/Conv2D tự cài), tf.data pipeline tối ưu, custom training loop bằng GradientTape, MirroredStrategy nếu có nhiều GPU - so sánh tốc độ và độ chính xác cuối cùng với bản PyTorch.
Ngày 97: Checkpoint & Review Giai đoạn 3
Mục tiêu: Củng cố kiến thức TF trước khi sang CNN.
Lý thuyết: Tổng hợp lại điểm khác biệt cốt lõi PyTorch vs TensorFlow: dynamic vs graph execution, DataLoader vs tf.data, autograd tự động vs GradientTape tường minh.
Thực hành: Tự trả lời không nhìn tài liệu: (1)
tf.functionretracing xảy ra khi nào, (2) format NHWC vs NCHW khác nhau ra sao, (3) thứ tự đúng của pipeline tf.data.
Checkpoint cuối Giai đoạn 3
Có thể giải thích sự khác biệt giữa Eager và Graph execution cho người mới không?
Pipeline tf.data đã tối ưu đủ để GPU không bị đói dữ liệu (idle) không?
Bản CIFAR-10 TensorFlow có đạt accuracy tương đương bản PyTorch không?
Nếu ổn, tiếp tục sang Giai đoạn 4 - CNN.
Giai Đoạn 4 - CNN (Ngày 98 - 115)
Mục tiêu giai đoạn: Hiểu toán học convolution tận gốc, tự implement các kiến trúc CNN kinh điển theo đúng trình tự lịch sử để thấy được logic tiến hoá của ý tưởng, và làm quen 2 bài toán ứng dụng lớn nhất: Detection & Segmentation.
Ngày 98: Toán học Convolution - Kernel, Padding, Stride
Mục tiêu: Hiểu convolution 2D ở mức công thức, không chỉ gọi API.
Lý thuyết: Phép convolution rời rạc 2D, vai trò kernel (bộ lọc), padding (same/valid), stride ảnh hưởng tới output size; công thức tính output shape.
Thực hành: Tính tay output shape cho vài cấu hình kernel/padding/stride, verify lại bằng code (dùng
MyConv2dđã cài ở Giai đoạn 2).
Ngày 99: Dilation & Receptive Field
Mục tiêu: Hiểu cách mở rộng receptive field mà không tăng số tham số.
Lý thuyết: Dilated/Atrous convolution (chèn khoảng trống giữa các phần tử kernel), công thức tính receptive field tích luỹ qua nhiều layer - kiến thức sẽ dùng lại ở DeepLab.
Thực hành: Viết hàm tính receptive field cho một chuỗi layer bất kỳ (kernel/stride/dilation cho trước), verify bằng cách vẽ sơ đồ trên giấy cho mạng 3-4 layer.
Ngày 100: LeNet - Kiến trúc CNN Đầu Tiên
Mục tiêu: Hiểu kiến trúc CNN sơ khai nhất, đặt nền cho các kiến trúc sau.
Lý thuyết: Cấu trúc LeNet-5 (Conv → Pool xen kẽ → Fully Connected), bối cảnh lịch sử (nhận dạng chữ số viết tay).
Thực hành: Implement LeNet từ đầu (dùng layer tự cài Giai đoạn 2), train trên MNIST, đạt accuracy tham chiếu (~99%).
Ngày 101: AlexNet - Bước Ngoặt Deep Learning
Mục tiêu: Hiểu các đổi mới giúp AlexNet tạo ra cú hích ImageNet 2012.
Lý thuyết: ReLU thay Sigmoid/Tanh, Dropout chống overfitting, Local Response Normalization, data augmentation quy mô lớn, huấn luyện trên nhiều GPU.
Thực hành: Implement AlexNet (rút gọn cho phù hợp dataset nhỏ hơn ImageNet, vd CIFAR-10/Tiny-ImageNet), train và so sánh kết quả với LeNet.
Ngày 102: VGG - Độ Sâu và Kernel Nhỏ
Mục tiêu: Hiểu insight quan trọng: chồng nhiều kernel 3×3 hiệu quả hơn 1 kernel lớn.
Lý thuyết: Vì sao 2 lớp conv 3×3 liên tiếp có cùng receptive field với 1 lớp 5×5 nhưng ít tham số hơn và có thêm phi tuyến; kiến trúc VGG16/VGG19.
Thực hành: Implement khối VGG (Conv-Conv-Pool lặp lại), train một phiên bản rút gọn trên CIFAR-10.
Ngày 103: Inception (GoogLeNet)
Mục tiêu: Hiểu ý tưởng trích xuất đặc trưng đa tỉ lệ trong cùng một layer.
Lý thuyết: Inception module (chạy song song nhiều kernel size 1×1/3×3/5×5 rồi concat), vai trò của conv 1×1 để giảm chiều (dimensionality reduction) trước khi conv tốn kém.
Thực hành: Implement 1 Inception module từ đầu, ghép vài module thành mini-GoogLeNet, train trên CIFAR-10.
Ngày 104: ResNet - Residual Connection
Mục tiêu: Hiểu ý tưởng quan trọng nhất giúp train được mạng cực sâu - nền tảng của mọi kiến trúc hiện đại kể cả Transformer.
Lý thuyết: Vấn đề degradation ở mạng rất sâu (không phải overfitting mà là khó tối ưu), residual connection (
y = F(x) + x) giúp gradient "đi tắt" qua các layer, giải quyết vanishing gradient.Thực hành: Implement 1 Residual Block từ đầu, so sánh trực tiếp: train mạng 20 layer có và không có residual connection, quan sát mạng không có residual bị degrade.
Ngày 105: ResNet - Bottleneck Block & Train Đầy Đủ
Mục tiêu: Hiểu biến thể hiệu quả hơn dùng trong ResNet-50/101/152.
Lý thuyết: Bottleneck block (1×1 giảm chiều → 3×3 → 1×1 tăng chiều lại) giúp giảm chi phí tính toán khi mạng sâu hơn.
Thực hành: Implement ResNet-18/34 style hoàn chỉnh (dùng basic block Ngày 104), train trên CIFAR-10 tới khi đạt kết quả tốt, lưu làm baseline model để so sánh với các kiến trúc sau.
Ngày 106: DenseNet - Dense Connections
Mục tiêu: Hiểu một hướng tiếp cận khác cho vấn đề gradient flow: kết nối mọi layer với nhau thay vì chỉ layer liền kề.
Lý thuyết: Dense block (mỗi layer nhận concat toàn bộ feature map từ các layer trước), feature reuse giúp giảm số tham số so với ResNet ở cùng độ sâu, growth rate.
Thực hành: Implement 1 Dense Block, so sánh số tham số và accuracy với ResNet cùng độ sâu trên CIFAR-10.
Ngày 107: EfficientNet - Compound Scaling
Mục tiêu: Hiểu cách scale mạng một cách có hệ thống thay vì tăng ngẫu nhiên depth/width/resolution.
Lý thuyết: Compound scaling (tăng đồng thời depth, width, resolution theo tỉ lệ cố định tối ưu qua neural architecture search), MBConv block (depthwise separable convolution).
Thực hành: Implement depthwise separable convolution, so sánh số tham số/FLOPs với convolution thường ở cùng kích thước output.
Ngày 108: Review & Benchmark So Sánh Kiến Trúc CNN
Mục tiêu: Có cái nhìn tổng thể về sự tiến hoá của CNN qua các thế hệ.
Lý thuyết: Tổng hợp bảng so sánh: LeNet → AlexNet → VGG → Inception → ResNet → DenseNet → EfficientNet theo số tham số, accuracy trên ImageNet, insight cốt lõi của mỗi kiến trúc.
Thực hành: Chạy benchmark tất cả các model đã cài (Ngày 100-107) trên cùng CIFAR-10, cùng epoch, lập bảng so sánh accuracy/số tham số/thời gian train.
Ngày 109: Object Detection - Bài Toán & Metric
Mục tiêu: Hiểu bài toán detection khác classification thế nào trước khi học các kiến trúc cụ thể.
Lý thuyết: Bounding box, IoU (Intersection over Union), Non-Maximum Suppression (NMS), mAP (mean Average Precision) làm metric đánh giá.
Thực hành: Cài đặt hàm tính IoU và NMS từ đầu bằng NumPy, test trên vài bounding box tự tạo.
Ngày 110: Faster R-CNN - Two-Stage Detection
Mục tiêu: Hiểu hướng tiếp cận two-stage (đề xuất vùng rồi phân loại).
Lý thuyết: Region Proposal Network (RPN) sinh candidate box, RoI Pooling để trích feature cho từng vùng, sau đó classify + refine box.
Thực hành: Đọc kiến trúc chi tiết, vẽ sơ đồ luồng dữ liệu qua Faster R-CNN, cài đặt (hoặc dùng lại) hàm RoI Pooling đơn giản.
Ngày 111: SSD - Single Shot Detection
Mục tiêu: Hiểu hướng one-stage đầu tiên, đánh đổi tốc độ lấy accuracy.
Lý thuyết: SSD dự đoán trực tiếp box + class trên feature map ở nhiều tỉ lệ (multi-scale feature maps), anchor box.
Thực hành: Cài đặt cơ chế anchor box generation cho một feature map kích thước cho trước.
Ngày 112: YOLO - Implement Basic Detector
Mục tiêu: Tự tay cài một detector one-stage đơn giản để hiểu tận gốc.
Lý thuyết: YOLO chia ảnh thành grid, mỗi cell dự đoán box + confidence + class trực tiếp; loss function kết hợp (localization + confidence + classification).
Thực hành: Implement một YOLO-style detector rút gọn (grid nhỏ, ít class) trên dataset toy, train và visualize bounding box dự đoán.
Ngày 113: Semantic Segmentation - FCN
Mục tiêu: Chuyển tư duy từ "dự đoán 1 nhãn/ảnh" sang "dự đoán 1 nhãn/pixel".
Lý thuyết: Fully Convolutional Network (thay fully-connected layer cuối bằng conv, giữ được thông tin không gian), transposed convolution (upsampling có học được).
Thực hành: Cài đặt transposed convolution từ đầu, verify output shape đúng như kỳ vọng khi upsample.
Ngày 114: U-Net - Encoder-Decoder với Skip Connection
Mục tiêu: Implement kiến trúc segmentation phổ biến nhất, đặc biệt trong y tế.
Lý thuyết: Cấu trúc encoder (downsampling, trích đặc trưng) - decoder (upsampling, khôi phục độ phân giải) đối xứng, skip connection nối trực tiếp encoder→decoder để giữ chi tiết không gian bị mất khi downsample.
Thực hành: Implement U-Net đầy đủ từ đầu, train trên dataset segmentation nhỏ (vd toy dataset phân đoạn hình đơn giản), visualize mask dự đoán.
Ngày 115: DeepLab & Checkpoint Giai đoạn 4
Mục tiêu: Hoàn thiện bức tranh segmentation hiện đại, tổng kết giai đoạn.
Lý thuyết: DeepLab dùng Atrous/Dilated Convolution (đã học Ngày 99) để giữ receptive field lớn mà không giảm độ phân giải quá nhiều; Atrous Spatial Pyramid Pooling (ASPP) kết hợp nhiều dilation rate.
Thực hành: Cài đặt ASPP module đơn giản (nhiều nhánh dilated conv song song rồi concat); tự kiểm tra: giải thích được sự khác biệt FCN → U-Net → DeepLab bằng lời cho người mới.
Checkpoint cuối Giai đoạn 4
Có thể tự vẽ sơ đồ và implement lại ResNet block từ trí nhớ không?
Hiểu rõ IoU, NMS, mAP đủ để giải thích cho người khác không?
U-Net tự cài có segment đúng trên dataset toy không?
Nếu ổn, tiếp tục sang Giai đoạn 5 - Sequence Models.
Giai Đoạn 5 - Sequence Models (Ngày 116 - 129)
Mục tiêu giai đoạn: Hiểu tận gốc các kiến trúc xử lý chuỗi trước Transformer, đặc biệt là cơ chế Attention - bước đệm trực tiếp và bắt buộc trước khi vào Giai đoạn 6.
Ngày 116: Vanilla RNN - Khái Niệm
Mục tiêu: Hiểu cách mạng neural xử lý dữ liệu tuần tự (thứ CNN/MLP không làm được).
Lý thuyết: Hidden state truyền qua từng timestep (
h_t = f(W_h·h_{t-1} + W_x·x_t + b)), unrolling RNN qua thời gian thành một mạng "sâu" tương đương.Thực hành: Vẽ tay sơ đồ unroll một RNN qua 4 timestep, tính tay forward pass cho chuỗi độ dài 3 với input/weight số cụ thể.
Ngày 117: Backpropagation Through Time (BPTT)
Mục tiêu: Hiểu vì sao RNN vanilla khó train trên chuỗi dài.
Lý thuyết: Gradient phải lan truyền ngược qua tất cả timestep, tích luỹ tích của nhiều đạo hàm giống nhau → vanishing gradient (nếu <1) hoặc exploding gradient (nếu >1) khi chuỗi dài.
Thực hành: Thực nghiệm train RNN vanilla trên chuỗi ngày càng dài (10, 50, 200 bước), quan sát gradient norm ở timestep đầu giảm dần về 0 khi chuỗi dài ra.
Ngày 118: Implement Vanilla RNN Từ Đầu
Mục tiêu: Biến lý thuyết Ngày 116-117 thành code chạy được.
Lý thuyết: Ôn lại công thức forward, cách autograd của PyTorch tự xử lý BPTT khi unroll bằng vòng lặp Python.
Thực hành: Implement
MyRNNCellbằngnn.Module(không dùngnn.RNNcó sẵn), train trên bài toán toy (dự đoán ký tự tiếp theo trong chuỗi đơn giản), so sánh kết quả vớinn.RNN.
Ngày 119: LSTM - Forget Gate
Mục tiêu: Bắt đầu hiểu cơ chế LSTM giải quyết vanishing gradient thế nào.
Lý thuyết: Ý tưởng cell state (
C_t) như một "băng chuyền" thông tin xuyên suốt, forget gate (f_t = σ(...)) quyết định giữ lại bao nhiêu thông tin cũ.Thực hành: Vẽ sơ đồ LSTM cell, tô màu riêng luồng đi của forget gate, giải thích bằng lời vì sao cấu trúc cộng (thay vì nhân liên tục như RNN) giúp gradient ổn định hơn.
Ngày 120: LSTM - Input, Output Gate & Cell State
Mục tiêu: Hoàn thiện hiểu biết về toàn bộ 3 gate của LSTM.
Lý thuyết: Input gate (
i_t) quyết định thông tin mới nào được thêm vào cell state, output gate (o_t) quyết định phần nào của cell state được lộ ra thành hidden state; công thức đầy đủ updateC_tvàh_t.Thực hành: Tính tay forward pass 1 bước LSTM với số liệu cụ thể cho cả 3 gate + cell state, verify bằng code.
Ngày 121: Implement LSTM Từ Đầu
Mục tiêu: Tự cài LSTM hoàn chỉnh, không dùng
nn.LSTM.Lý thuyết: Ôn lại toàn bộ 4 công thức (forget/input/output gate + candidate cell state) và cách ghép chúng lại.
Thực hành: Implement
MyLSTMCell, train trên cùng bài toán Ngày 118, so sánh khả năng học chuỗi dài hơn so với RNN vanilla (thực nghiệm trực tiếp trên chuỗi dài).
Ngày 122: GRU - So Sánh Với LSTM
Mục tiêu: Hiểu biến thể đơn giản hơn nhưng thường hiệu quả tương đương LSTM.
Lý thuyết: GRU gộp forget+input gate thành update gate, bỏ cell state riêng (chỉ dùng hidden state), reset gate; ít tham số hơn LSTM (2 gate thay vì 3).
Thực hành: Lập bảng so sánh công thức LSTM vs GRU song song, chỉ ra rõ điểm nào bị gộp/bỏ.
Ngày 123: Implement GRU & Benchmark
Mục tiêu: Có số liệu thực nghiệm để tự đánh giá GRU vs LSTM thay vì chỉ đọc lý thuyết.
Lý thuyết: Ôn công thức GRU đầy đủ.
Thực hành: Implement
MyGRUCell, benchmark cả 3 (RNN/LSTM/GRU) trên cùng bài toán: tốc độ train, số tham số, accuracy cuối cùng - tự rút kết luận.
Ngày 124: Seq2Seq - Kiến Trúc Encoder-Decoder
Mục tiêu: Hiểu cách xử lý bài toán chuỗi-sang-chuỗi (input/output độ dài khác nhau).
Lý thuyết: Encoder nén toàn bộ input thành 1 context vector (hidden state cuối), decoder sinh output từng bước dựa vào context vector đó; teacher forcing khi train (dùng ground-truth token trước thay vì token model tự sinh).
Thực hành: Vẽ sơ đồ luồng dữ liệu Seq2Seq đầy đủ cho một câu ví dụ, chỉ rõ điểm nào dùng teacher forcing.
Ngày 125: Implement Seq2Seq Cho Bài Toán Toy
Mục tiêu: Có một Seq2Seq chạy được thực tế.
Lý thuyết: Ôn lại cách ghép encoder (LSTM/GRU Ngày 121/123) với decoder.
Thực hành: Implement Seq2Seq hoàn chỉnh cho bài toán toy (vd đảo ngược chuỗi số, hoặc "dịch" chuỗi ký tự sang chuỗi khác theo quy tắc cố định), train và đánh giá.
Ngày 126: Attention Mechanism - Giải Quyết Nút Thắt Context Vector
Mục tiêu: Hiểu vấn đề cốt lõi Attention giải quyết - nền tảng trực tiếp cho Transformer ở Giai đoạn 6.
Lý thuyết: Vấn đề: context vector cố định của Seq2Seq trở thành nút thắt cổ chai khi câu dài (mất thông tin); Bahdanau Attention (additive) và Luong Attention (multiplicative) cho phép decoder "nhìn lại" toàn bộ hidden state của encoder ở mỗi bước, tính trọng số attention động.
Thực hành: Cài đặt hàm tính attention score và attention weight (softmax) bằng NumPy/PyTorch thuần, verify tổng trọng số attention = 1.
Ngày 127: Implement Attention Trên Seq2Seq
Mục tiêu: Tích hợp Attention vào Seq2Seq đã xây Ngày 125, đo sự cải thiện thực tế.
Lý thuyết: Ôn lại cách attention weight kết hợp với encoder hidden states để tạo context vector động cho mỗi bước decode.
Thực hành: Thêm attention layer vào Seq2Seq Ngày 125, so sánh chất lượng output trên chuỗi dài với bản không có attention, visualize attention weight bằng heatmap.
Ngày 128: Project - Char-level Language Model với LSTM + Attention
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 5 vào một project hoàn chỉnh.
Lý thuyết: Ôn lại toàn bộ pipeline: embedding ký tự → LSTM/GRU → attention (nếu áp dụng) → dự đoán ký tự tiếp theo.
Thực hành: Train một char-level language model (dùng LSTM tự cài) trên một corpus text nhỏ, sinh văn bản mới bằng sampling từ model đã train, đánh giá chất lượng văn bản sinh ra.
Ngày 129: Checkpoint & Review Giai đoạn 5
Mục tiêu: Củng cố trước khi bước vào phần quan trọng nhất của toàn lộ trình - Transformer.
Lý thuyết: Tổng hợp lại: RNN → vấn đề vanishing gradient → LSTM/GRU giải quyết bằng gate → Seq2Seq gặp nút thắt context vector → Attention giải quyết bằng cách nhìn toàn bộ chuỗi. Đây chính xác là mạch tư duy dẫn tới câu nói nổi tiếng "Attention Is All You Need" ở Giai đoạn 6.
Thực hành: Tự kiểm tra: vẽ lại từ trí nhớ sơ đồ LSTM cell đầy đủ 3 gate; giải thích bằng lời tại sao Attention giải quyết được nút thắt cổ chai của Seq2Seq thuần.
Checkpoint cuối Giai đoạn 5
Có thể giải thích rõ ràng sự khác biệt RNN/LSTM/GRU cho người mới không?
Attention weight visualize có "nhìn hợp lý" không (tập trung đúng vào phần liên quan của input)?
Đã sẵn sàng tinh thần: đây là bước đệm trực tiếp cho Transformer - phần quan trọng nhất của lộ trình.
Tiếp tục sang Giai đoạn 6 - Transformer & LLM hiện đại (giai đoạn dài nhất, 45 ngày).
Giai Đoạn 6 - Transformer & LLM Hiện Đại (Ngày 130 - 174)
Đây là giai đoạn quan trọng nhất của toàn lộ trình. Mục tiêu: hiểu tận gốc Transformer, các kỹ thuật tối ưu attention hiện đại (Flash Attention, GQA, quantization, LoRA), và toàn bộ pipeline huấn luyện LLM từ pretraining tới alignment.
Ngày 130: Scaled Dot Product Attention - Dẫn Xuất Toán Học
Mục tiêu: Hiểu công thức attention nổi tiếng
Attention(Q,K,V) = softmax(QK^T/√d_k)Vtừ đâu ra.Lý thuyết: Q (Query), K (Key), V (Value) đại diện cho điều gì; vì sao chia cho
√d_k(tránh dot product quá lớn làm softmax bão hoà - liên hệ vấn đề saturation đã học ở Giai đoạn 1); mối liên hệ trực tiếp với Attention đã học ở Giai đoạn 5 (đây là dạng tổng quát hoá).Thực hành: Tính tay attention output cho một ví dụ nhỏ (3 token, dimension nhỏ) trên giấy, verify bằng code NumPy.
Ngày 131: Implement Scaled Dot Product Attention
Mục tiêu: Biến công thức thành code chuẩn.
Lý thuyết: Ôn lại numerical stability của softmax (log-sum-exp đã học ở Giai đoạn 1, Ngày 27).
Thực hành: Implement
scaled_dot_product_attention()bằng PyTorch thuần (không dùngF.scaled_dot_product_attention), verify gradient bằng numerical checking, so sánh với hàm built-in.
Ngày 132: Multi-Head Attention - Khái Niệm
Mục tiêu: Hiểu vì sao dùng nhiều "head" thay vì 1 attention lớn.
Lý thuyết: Mỗi head học một kiểu quan hệ khác nhau giữa các token (subspace khác nhau); chia
d_modelthànhhhead, mỗi head dimensiond_model/h, sau đó concat lại và chiếu quaW_O.Thực hành: Vẽ sơ đồ luồng dữ liệu Multi-Head Attention đầy đủ (từ input → chia head → attention song song → concat → linear projection).
Ngày 133: Implement Multi-Head Attention Từ Đầu
Mục tiêu: Có module MHA hoàn chỉnh tự viết, không dùng
nn.MultiheadAttention.Lý thuyết: Ôn lại cách reshape tensor hiệu quả để tính song song nhiều head bằng phép nhân ma trận batched (không dùng vòng lặp Python qua từng head).
Thực hành: Implement
MyMultiHeadAttention, so sánh output vớinn.MultiheadAttentiontrên cùng trọng số khởi tạo, benchmark tốc độ.
Ngày 134: Positional Encoding - Vì Sao Cần Thiết
Mục tiêu: Hiểu một hạn chế cốt lõi của attention thuần.
Lý thuyết: Attention là permutation-invariant (đổi thứ tự token không đổi kết quả nếu không có thông tin vị trí) - khác biệt căn bản với RNN (vốn xử lý tuần tự nên tự nhiên biết thứ tự); cần thêm thông tin vị trí một cách tường minh.
Thực hành: Thực nghiệm: xáo trộn thứ tự token đầu vào của một attention layer, verify output (trước khi thêm positional encoding) không đổi ngoại trừ thứ tự - chứng minh bằng thực nghiệm cho luận điểm lý thuyết.
Ngày 135: Sinusoidal Positional Encoding
Mục tiêu: Hiểu và implement phương pháp gốc trong paper "Attention Is All You Need".
Lý thuyết: Công thức sin/cos với tần số khác nhau theo từng chiều; tính chất cho phép model suy luận vị trí tương đối thông qua tổ hợp tuyến tính (do tính chất lượng giác).
Thực hành: Implement Sinusoidal PE bằng NumPy, visualize ma trận positional encoding dưới dạng heatmap để thấy pattern tần số.
Ngày 136: RoPE - Rotary Positional Encoding
Mục tiêu: Hiểu phương pháp positional encoding dùng trong hầu hết LLM hiện đại (LLaMA, Mistral, DeepSeek, Qwen).
Lý thuyết: Ý tưởng "xoay" vector Q/K trong không gian theo góc phụ thuộc vị trí, giúp encode được cả vị trí tuyệt đối lẫn tương đối một cách tự nhiên qua dot product; ưu điểm so với sinusoidal cộng trực tiếp (không làm nhiễu magnitude của embedding).
Thực hành: Implement RoPE từ đầu (áp dụng phép xoay lên Q, K trước khi tính attention), verify tính chất: dot product của 2 vector đã áp RoPE chỉ phụ thuộc vào khoảng cách tương đối giữa 2 vị trí.
Ngày 137: ALiBi - Attention with Linear Biases
Mục tiêu: Biết một hướng tiếp cận khác cho positional information, đặc biệt tốt cho extrapolation sang chuỗi dài hơn lúc train.
Lý thuyết: ALiBi không sửa Q/K mà cộng trực tiếp một bias tuyến tính (tỉ lệ với khoảng cách) vào attention score trước softmax; ưu điểm cho phép model xử lý chuỗi dài hơn train time tốt hơn RoPE trong một số trường hợp.
Thực hành: Implement ALiBi bias, so sánh sơ đồ hoạt động và trade-off với RoPE (đã học Ngày 136) trong một bảng so sánh.
Ngày 138: Transformer Encoder Block - Kiến Trúc & Pre-Norm vs Post-Norm
Mục tiêu: Hiểu cấu trúc đầy đủ 1 block Transformer trước khi implement.
Lý thuyết: Thứ tự: Multi-Head Attention → Add & Norm → Feed-Forward Network (FFN) → Add & Norm; khác biệt Post-LN (bản gốc paper) vs Pre-LN (chuẩn hiện đại, ổn định hơn khi train mạng rất sâu) - vì sao hầu hết LLM hiện nay dùng Pre-LN.
Thực hành: Vẽ sơ đồ chi tiết 2 biến thể Pre-LN và Post-LN cạnh nhau, chỉ rõ điểm khác biệt vị trí LayerNorm.
Ngày 139: Implement Transformer Encoder Block
Mục tiêu: Có 1 encoder block hoàn chỉnh, tái sử dụng cho các ngày sau.
Lý thuyết: Ôn lại FFN (2 lớp Linear với activation ở giữa, thường GELU - đã học Giai đoạn 1), residual connection (đã hiểu sâu ở ResNet, Giai đoạn 4).
Thực hành: Implement
TransformerEncoderBlock(Pre-LN) dùng MHA đã cài Ngày 133, verify shape input/output không đổi qua block (tính chất quan trọng để stack nhiều block).
Ngày 140: Transformer Decoder Block - Masked Self-Attention & Cross-Attention
Mục tiêu: Hiểu 2 điểm khác biệt của decoder so với encoder.
Lý thuyết: Masked (causal) self-attention - che các token tương lai bằng attention mask (giá trị
-inftrước softmax) để đảm bảo tính autoregressive; cross-attention - Q lấy từ decoder, K/V lấy từ output encoder (chỉ có trong kiến trúc encoder-decoder như T5, không có trong GPT thuần decoder-only).Thực hành: Implement causal mask, verify token ở vị trí
tchỉ có attention weight khác 0 với token≤ t.
Ngày 141: Implement Transformer Decoder Block
Mục tiêu: Có decoder block hoàn chỉnh.
Lý thuyết: Ôn lại thứ tự: Masked MHA → Add&Norm → Cross-Attention (nếu có) → Add&Norm → FFN → Add&Norm.
Thực hành: Implement
TransformerDecoderBlock, test với causal mask Ngày 140.
Ngày 142: Full Transformer - Lắp Ráp Hoàn Chỉnh
Mục tiêu: Có kiến trúc Transformer đầy đủ giống paper gốc.
Lý thuyết: Ghép Embedding + Positional Encoding → N encoder block → N decoder block → output projection + softmax.
Thực hành: Implement class
Transformerhoàn chỉnh (encoder-decoder), verify forward pass chạy đúng shape từ đầu tới cuối trên input giả.
Ngày 143: Train Transformer Trên Bài Toán Toy
Mục tiêu: Chứng minh Transformer tự cài hoạt động thực tế, so sánh với Seq2Seq+Attention đã làm ở Giai đoạn 5.
Lý thuyết: Ôn lại toàn bộ training loop chuẩn đã xây ở Giai đoạn 2.
Thực hành: Train Transformer tự cài trên cùng bài toán toy đã dùng ở Giai đoạn 5 (Ngày 125), so sánh tốc độ hội tụ và chất lượng với bản LSTM+Attention.
Ngày 144: Tokenization - Thuật Toán BPE
Mục tiêu: Hiểu cách văn bản được chuyển thành token trước khi vào model.
Lý thuyết: Byte Pair Encoding (BPE) - thuật toán gộp lặp cặp ký tự/subword xuất hiện nhiều nhất thành 1 token mới, xây vocabulary dần từ ký tự đơn tới subword.
Thực hành: Chạy tay thuật toán BPE trên một corpus nhỏ (vài câu) qua 5-10 vòng gộp, ghi lại vocabulary hình thành từng bước.
Ngày 145: Implement BPE Tokenizer Từ Đầu
Mục tiêu: Có tokenizer BPE hoạt động thực tế.
Lý thuyết: Ôn lại thuật toán, cách encode văn bản mới bằng vocabulary đã học (áp dụng các rule gộp theo đúng thứ tự đã học).
Thực hành: Implement BPE tokenizer hoàn chỉnh (train + encode + decode) bằng Python thuần, train trên corpus nhỏ, so sánh vocabulary/kết quả encode với tokenizer của Hugging Face (chỉ để đối chiếu, không dùng lại code).
Ngày 146: WordPiece & SentencePiece
Mục tiêu: Biết các biến thể tokenization khác và khi nào dùng loại nào.
Lý thuyết: WordPiece (dùng trong BERT, chọn gộp theo likelihood thay vì tần suất thuần) và SentencePiece (xử lý văn bản thô không cần pre-tokenize theo khoảng trắng, phù hợp đa ngôn ngữ - dùng trong T5, LLaMA).
Thực hành: Lập bảng so sánh BPE vs WordPiece vs SentencePiece (thuật toán, framework sử dụng, ưu/nhược điểm), thử tokenize cùng 1 câu tiếng Việt bằng vài tokenizer có sẵn để so sánh cách tách token.
Ngày 147: BERT - Kiến Trúc Encoder-Only
Mục tiêu: Hiểu kiến trúc và mục tiêu pretraining của BERT.
Lý thuyết: BERT chỉ dùng Transformer Encoder (không có phần decoder/causal mask); 2 mục tiêu pretraining: Masked Language Modeling (MLM - che ngẫu nhiên 15% token, dự đoán lại) và Next Sentence Prediction (NSP).
Thực hành: Cài đặt hàm masking ngẫu nhiên cho MLM (theo đúng tỉ lệ 80% [MASK]/10% random token/10% giữ nguyên như paper gốc).
Ngày 148: Implement BERT-style Masked LM Pretraining (Quy Mô Nhỏ)
Mục tiêu: Thực hành pretraining objective thực tế ở quy mô nhỏ.
Lý thuyết: Ôn lại encoder block đã cài Ngày 139, ghép với masking Ngày 147 và loss CrossEntropy chỉ tính trên vị trí bị mask.
Thực hành: Train một BERT-mini (vài layer, vocab nhỏ) trên corpus nhỏ với MLM objective, kiểm tra model có dự đoán đúng token bị che không.
Ngày 149: GPT - Kiến Trúc Decoder-Only
Mục tiêu: Hiểu kiến trúc chiếm ưu thế trong các LLM hiện đại (GPT, LLaMA, Mistral, DeepSeek, Qwen đều decoder-only).
Lý thuyết: Chỉ dùng Transformer Decoder không có cross-attention (bỏ phần dành cho encoder output vì không có encoder); Causal Language Modeling - dự đoán token tiếp theo dựa trên toàn bộ token trước đó.
Thực hành: So sánh sơ đồ kiến trúc BERT (encoder-only, Ngày 147) vs GPT (decoder-only) cạnh nhau, chỉ rõ khác biệt về attention mask và mục tiêu training.
Ngày 150: Implement GPT-style Model Từ Đầu
Mục tiêu: Có một GPT-mini hoạt động thực tế - nền tảng trực tiếp cho project train LLM nhỏ ở phần Capstone.
Lý thuyết: Ôn lại decoder block Ngày 141 (bỏ phần cross-attention vì không cần), causal LM loss (shift token 1 vị trí làm target).
Thực hành: Implement GPT-mini hoàn chỉnh, train trên corpus text nhỏ với causal LM objective, sinh văn bản bằng greedy/sampling decode.
Ngày 151: T5 - Text-to-Text Framework
Mục tiêu: Hiểu kiến trúc encoder-decoder hiện đại và cách chuẩn hoá mọi bài toán NLP thành dạng text-to-text.
Lý thuyết: T5 dùng đầy đủ encoder-decoder (như Transformer gốc), pretraining bằng span corruption (che một đoạn liên tục token thay vì từng token rời rạc như BERT); mọi task (dịch, tóm tắt, phân loại) đều format thành input text → output text.
Thực hành: Cài đặt hàm span corruption masking, so sánh với random token masking của BERT (Ngày 147).
Ngày 152: So Sánh BERT vs GPT vs T5 - Khi Nào Dùng Kiến Trúc Nào
Mục tiêu: Có tư duy hệ thống để chọn đúng kiến trúc cho bài toán thực tế.
Lý thuyết: Encoder-only (BERT) phù hợp task hiểu văn bản (classification, NER, không cần sinh text); Decoder-only (GPT) phù hợp sinh văn bản tự do, là lựa chọn mặc định cho LLM hiện đại vì khả năng scale tốt; Encoder-decoder (T5) phù hợp task chuyển đổi có cấu trúc rõ (dịch, tóm tắt).
Thực hành: Viết bảng quyết định (decision table): cho 5-6 bài toán NLP thực tế, chọn kiến trúc phù hợp nhất và giải thích lý do.
(Còn tiếp: Ngày 153-174 trong phần tiếp theo - KV Cache, Flash Attention, GQA/MQA, Sliding Window Attention, LLaMA/Mistral/DeepSeek/Qwen, LLM Training Pipeline, Quantization, PEFT/LoRA)
Ngày 153: KV Cache - Khái Niệm
Mục tiêu: Hiểu kỹ thuật tối ưu inference quan trọng bậc nhất cho LLM autoregressive.
Lý thuyết: Khi sinh token tự hồi quy, K và V của các token đã sinh không đổi qua các bước - thay vì tính lại toàn bộ attention mỗi lần sinh token mới, cache lại K/V để chỉ cần tính cho token mới nhất; đánh đổi giữa tốc độ (nhanh hơn nhiều) và bộ nhớ (cache tăng theo độ dài chuỗi × số layer × số head).
Thực hành: Vẽ sơ đồ minh hoạ inference không có cache (tính lại toàn bộ mỗi bước) vs có cache (chỉ tính phần mới), ước tính bằng công thức lượng bộ nhớ cache cần cho 1 model cụ thể (số layer, hidden dim, số head cho trước).
Ngày 154: Implement KV Cache & Benchmark
Mục tiêu: Thấy rõ hiệu quả KV Cache bằng số liệu thực nghiệm.
Lý thuyết: Ôn lại cấu trúc GPT-mini đã cài Ngày 150.
Thực hành: Thêm KV Cache vào GPT-mini, benchmark tốc độ sinh văn bản (token/giây) có/không có cache trên chuỗi output dài, đo thêm VRAM sử dụng khi cache tăng dần.
Ngày 155: Flash Attention - Động Lực & Ý Tưởng Cốt Lõi
Mục tiêu: Hiểu vì sao attention chuẩn chậm ở chuỗi dài và Flash Attention giải quyết thế nào.
Lý thuyết: Attention chuẩn cần vật chất hoá (materialize) ma trận attention
N×Nđầy đủ trong bộ nhớ GPU - tốn bộ nhớ bậc 2 theo độ dài chuỗi và chậm vì phải đọc/ghi HBM (GPU memory) nhiều lần; Flash Attention dùng kỹ thuật tiling (chia nhỏ Q/K/V thành block, tính toán trong SRAM nhanh của GPU) để tránh materialize ma trận đầy đủ.Thực hành: Đọc kiến trúc GPU (SRAM vs HBM, sẽ học sâu ở Giai đoạn 9) để hiểu vì sao giảm số lần đọc/ghi HBM lại quan trọng đến vậy; vẽ sơ đồ so sánh luồng dữ liệu attention chuẩn vs Flash Attention.
Ngày 156: Flash Attention - Online Softmax & Sử Dụng Thực Tế
Mục tiêu: Hiểu chi tiết kỹ thuật giúp Flash Attention tính đúng softmax dù xử lý theo từng block nhỏ.
Lý thuyết: Online softmax - kỹ thuật cập nhật dần giá trị max và tổng exp khi xử lý từng block K/V mà không cần thấy toàn bộ hàng cùng lúc, đảm bảo kết quả toán học chính xác giống softmax đầy đủ.
Thực hành: Cài đặt thư viện
flash-attn(hoặc dùngF.scaled_dot_product_attentionvới backend Flash Attention có sẵn trong PyTorch), benchmark tốc độ và VRAM so với attention thuần đã cài Ngày 131 trên chuỗi dài.
Ngày 157: Grouped Query Attention (GQA) & Multi-Query Attention (MQA)
Mục tiêu: Hiểu kỹ thuật giảm kích thước KV Cache - vấn đề thực tế nghiêm trọng khi serving LLM ở quy mô lớn.
Lý thuyết: MQA - nhiều Query head nhưng chỉ 1 Key/Value head dùng chung (giảm mạnh KV cache nhưng giảm chất lượng); GQA - điểm cân bằng, nhóm nhiều Query head dùng chung 1 nhóm Key/Value head (thay vì 1-1 như MHA chuẩn hay 1 chung như MQA); LLaMA-2/3, Mistral đều dùng GQA.
Thực hành: Vẽ sơ đồ so sánh 3 cơ chế MHA vs GQA vs MQA, tính toán kích thước KV cache tiết kiệm được khi chuyển từ MHA sang GQA cho 1 cấu hình model cụ thể.
Ngày 158: Implement GQA & Đánh Giá Trade-off
Mục tiêu: Có số liệu thực nghiệm về đánh đổi bộ nhớ/chất lượng của GQA.
Lý thuyết: Ôn lại Multi-Head Attention Ngày 133, cách sửa để nhóm nhiều Q head share chung K/V head.
Thực hành: Sửa
MyMultiHeadAttentionthànhMyGroupedQueryAttention(tham số hoá số group), train và so sánh chất lượng + VRAM cache giữa MHA thường và GQA trên cùng bài toán.
Ngày 159: Sliding Window Attention
Mục tiêu: Hiểu kỹ thuật giới hạn attention theo cửa sổ cục bộ, dùng trong Mistral.
Lý thuyết: Thay vì attention toàn bộ chuỗi (
O(N²)), mỗi token chỉ attend tớiWtoken gần nhất; qua nhiều layer, receptive field vẫn mở rộng dần (tương tự ý tưởng receptive field của CNN đã học Giai đoạn 4) mà không cần tính attention toàn cục ở mỗi layer.Thực hành: Implement sliding window mask, so sánh chi phí tính toán (số phép tính attention) giữa full attention và sliding window attention theo độ dài chuỗi.
Ngày 160: LLaMA
Mục tiêu: Hiểu kiến trúc LLM mã nguồn mở có ảnh hưởng nhất, tổng hợp các kỹ thuật đã học.
Lý thuyết: RMSNorm thay LayerNorm (đơn giản hơn, chỉ chuẩn hoá theo RMS không trừ mean, nhanh hơn); SwiGLU activation trong FFN (thay GELU/ReLU thường); RoPE (đã học Ngày 136) cho positional encoding; Pre-Norm (đã học Ngày 138).
Thực hành: Cài đặt RMSNorm và SwiGLU từ đầu bằng PyTorch, so sánh công thức và tốc độ với LayerNorm/GELU đã cài trước đó.
Ngày 161: Implement LLaMA-style Block Hoàn Chỉnh
Mục tiêu: Có 1 block LLaMA-style tự cài, tái sử dụng cho project train LLM nhỏ ở Capstone.
Lý thuyết: Ôn lại toàn bộ: RMSNorm + RoPE + GQA (Ngày 158) + SwiGLU FFN, ghép theo đúng thứ tự Pre-Norm.
Thực hành: Implement
LlamaBlockđầy đủ, ghép nhiều block thành mini-LLaMA, forward-pass test trên input giả.
Ngày 162: Mistral - Sliding Window + GQA Kết Hợp
Mục tiêu: Hiểu cách Mistral tối ưu hoá thêm dựa trên nền LLaMA-style.
Lý thuyết: Mistral kết hợp Sliding Window Attention (Ngày 159) với GQA (Ngày 157/158) để vừa giảm KV cache vừa giảm chi phí tính toán attention; Rolling Buffer Cache - biến thể KV cache tận dụng sliding window để giới hạn kích thước cache cố định bất kể độ dài chuỗi.
Thực hành: Sửa
LlamaBlockNgày 161 để thêm sliding window mask, so sánh throughput/VRAM với bản LLaMA-style gốc trên chuỗi dài.
Ngày 163: DeepSeek - MoE & Multi-Head Latent Attention
Mục tiêu: Làm quen 2 kỹ thuật tiên tiến nhất hiện nay trong kiến trúc LLM.
Lý thuyết: Mixture of Experts (MoE) - thay 1 FFN dày đặc bằng nhiều "expert" FFN nhỏ, mỗi token chỉ đi qua top-k expert (routing), cho phép tăng tổng số tham số mà không tăng tương ứng chi phí tính toán mỗi token; Multi-Head Latent Attention (MLA) - nén K/V thành không gian latent chiều thấp trước khi cache, giảm mạnh KV cache hơn cả GQA.
Thực hành: Vẽ sơ đồ routing của MoE (gating network chọn top-k expert cho mỗi token), tính ví dụ số tham số "active" vs "total" của một MoE cấu hình cụ thể.
Ngày 164: Qwen & Tổng Quan Các Họ Model Mã Nguồn Mở
Mục tiêu: Có bức tranh toàn cảnh về hệ sinh thái LLM mã nguồn mở hiện nay.
Lý thuyết: Điểm đặc trưng của Qwen (tokenizer đa ngôn ngữ mạnh, context dài); tổng hợp so sánh LLaMA/Mistral/DeepSeek/Qwen theo: attention variant, normalization, activation, MoE hay dense.
Thực hành: Lập bảng so sánh chi tiết 4 kiến trúc theo các tiêu chí trên (dùng tool search để lấy thông tin cấu hình mới nhất nếu cần, vì các model này cập nhật liên tục).
Ngày 165: LLM Training Pipeline - Pretraining Data & Scaling Laws
Mục tiêu: Hiểu quy mô và chiến lược dữ liệu cho pretraining.
Lý thuyết: Nguồn dữ liệu pretraining (web crawl, sách, code...), data deduplication, data quality filtering; khái niệm scaling law (mối quan hệ giữa compute/data/model size và loss).
Thực hành: Đọc và tóm tắt (bằng lời riêng, không trích dẫn) ý tưởng chính của Chinchilla scaling law - tỉ lệ tối ưu giữa số tham số và số token training.
Ngày 166: Pretraining - Loss Curve & Compute Budget
Mục tiêu: Biết đọc và chẩn đoán một quá trình pretraining thực tế.
Lý thuyết: Đường loss pretraining điển hình, các dấu hiệu bất thường (loss spike - sẽ đào sâu cách debug ở Giai đoạn 9), khái niệm compute budget (FLOPs) và cách nó ràng buộc lựa chọn model size/data size.
Thực hành: Dùng GPT-mini đã cài Ngày 150, thử pretraining ở vài quy mô data khác nhau, vẽ loss curve và nhận xét theo tinh thần scaling law.
Ngày 167: SFT - Supervised Fine-Tuning
Mục tiêu: Hiểu bước biến 1 base model (chỉ biết "tiếp nối văn bản") thành model biết "làm theo chỉ dẫn".
Lý thuyết: Instruction tuning - fine-tune trên dataset dạng (instruction, response) với loss chỉ tính trên phần response (mask phần instruction); định dạng chat template phổ biến.
Thực hành: Chuẩn bị một dataset instruction nhỏ, viết hàm masking loss chỉ trên phần response.
Ngày 168: Implement SFT Fine-tune
Mục tiêu: Thực hành SFT thực tế trên model đã pretrain.
Lý thuyết: Ôn lại toàn bộ training loop, learning rate thường nhỏ hơn nhiều so với pretraining.
Thực hành: Fine-tune GPT-mini đã pretrain (Ngày 166) bằng SFT trên dataset instruction Ngày 167, so sánh chất lượng phản hồi trước/sau SFT.
Ngày 169: RLHF - Reward Model
Mục tiêu: Hiểu bước đầu tiên của alignment sau SFT.
Lý thuyết: Thu thập dữ liệu human preference (so sánh cặp response, chọn cái tốt hơn), train reward model để dự đoán điểm "chất lượng" của 1 response dựa trên dữ liệu preference đó (dùng Bradley-Terry loss).
Thực hành: Cài đặt loss function cho reward model (dựa trên cặp response tốt/xấu) bằng PyTorch, thử train trên dataset preference toy.
Ngày 170: RLHF - PPO Cho LLM Alignment
Mục tiêu: Hiểu tổng quan cách PPO dùng reward model để tối ưu policy (chính là LLM).
Lý thuyết: LLM đóng vai policy, reward model Ngày 169 cho điểm response được sinh ra, PPO cập nhật policy để tối đa hoá reward kỳ vọng trong khi giữ KL divergence với policy gốc không quá xa (tránh reward hacking).
Thực hành: Đọc sơ đồ pipeline RLHF đầy đủ (SFT model → reward model → PPO loop), vẽ lại bằng lời của mình, không cần code full pipeline (phức tạp và tốn compute) mà tập trung hiểu luồng dữ liệu.
Ngày 171: DPO - Direct Preference Optimization
Mục tiêu: Hiểu phương pháp thay thế RLHF/PPO đơn giản hơn, phổ biến hơn trong thực tế hiện nay.
Lý thuyết: DPO tái tham số hoá bài toán RLHF thành một loss function đơn giản có thể tối ưu trực tiếp bằng gradient descent trên dữ liệu preference, không cần reward model riêng và không cần vòng lặp RL phức tạp như PPO.
Thực hành: Implement DPO loss function bằng PyTorch, fine-tune model SFT Ngày 168 bằng DPO trên dataset preference toy, so sánh độ phức tạp cài đặt với RLHF/PPO.
Ngày 172: Quantization - INT8/INT4 Cơ Bản
Mục tiêu: Hiểu kỹ thuật giảm kích thước model để deploy hiệu quả - sẽ dùng trực tiếp ở Giai đoạn 10.
Lý thuyết: Quantization ánh xạ trọng số float32/float16 sang số nguyên int8/int4 để giảm bộ nhớ và tăng tốc; calibration (xác định scale/zero-point phù hợp bằng dữ liệu mẫu), symmetric vs asymmetric quantization.
Thực hành: Implement quantize/dequantize INT8 thủ công cho 1 tensor trọng số, đo sai số so với bản gốc float32.
Ngày 173: GPTQ, AWQ & bitsandbytes
Mục tiêu: Biết các thuật toán quantization nâng cao dùng thực tế cho LLM.
Lý thuyết: GPTQ (quantize theo từng layer dựa trên tối thiểu hoá sai số output, dùng thông tin Hessian xấp xỉ), AWQ (bảo vệ các kênh trọng số quan trọng dựa trên activation magnitude thay vì quantize đồng đều);
bitsandbytesnhư thư viện thực dụng phổ biến để load model 8-bit/4-bit trong PyTorch.Thực hành: Dùng
bitsandbytesload một model pretrained ở chế độ 4-bit, so sánh VRAM sử dụng và tốc độ inference với bản full precision.
Ngày 174: PEFT - LoRA, QLoRA & Checkpoint Giai đoạn 6
Mục tiêu: Hiểu kỹ thuật fine-tune hiệu quả tham số - gần như bắt buộc khi làm việc với LLM lớn có tài nguyên hạn chế, và tổng kết toàn bộ giai đoạn dài nhất của lộ trình.
Lý thuyết: LoRA - đóng băng trọng số gốc, chỉ train 2 ma trận rank-thấp
A,Bcộng thêm vào (W' = W + BA), giảm mạnh số tham số cần train; QLoRA kết hợp LoRA với quantization 4-bit (Ngày 172-173) để fine-tune model lớn trên GPU tài nguyên hạn chế; sơ lược Prefix Tuning (thêm token ảo có thể học vào đầu chuỗi) và Adapter (chèn thêm module nhỏ giữa các layer).Thực hành: Implement LoRA layer từ đầu (bọc quanh
nn.Linearcó sẵn, chỉ trainA/B), fine-tune GPT-mini bằng LoRA trên dataset instruction, so sánh số tham số trainable và VRAM với full fine-tuning. Sau đó tự kiểm tra toàn bộ Giai đoạn 6: vẽ lại từ trí nhớ sơ đồ đầy đủ 1 block LLaMA-style (RMSNorm+RoPE+GQA+SwiGLU), giải thích được KV Cache, Flash Attention, GQA, LoRA cho người không biết gì về LLM.
Checkpoint cuối Giai đoạn 6
Có thể implement lại Multi-Head Attention từ đầu trong 20 phút không nhìn tài liệu không?
Hiểu rõ sự khác biệt và đánh đổi giữa MHA/GQA/MQA không?
LoRA fine-tune có giảm đáng kể số tham số trainable mà vẫn giữ được chất lượng không?
Có thể vẽ toàn bộ pipeline Pretrain → SFT → RLHF/DPO cho người khác hiểu không?
Đây là giai đoạn nặng nhất - nếu cần, dành thêm 1-2 tuần ôn lại trước khi sang Giai đoạn 7 (PyTorch, đọc source code C++).
Giai Đoạn 7 - PyTorch (Ngày 175 - 209)
Mục tiêu giai đoạn: Đọc và hiểu source code PyTorch ở mức đủ sâu để biết chuyện gì xảy ra dưới lớp API Python - từ Tensor/Storage, Dispatcher, ATen, CUDA backend, tới TorchScript và torch.compile hiện đại.
Ngày 175: Tổng Quan Cấu Trúc Source Code PyTorch
Mục tiêu: Có bản đồ để không bị lạc khi đọc repo khổng lồ của PyTorch.
Lý thuyết: Cấu trúc thư mục chính:
torch/(Python API),aten/(C++ tensor library),c10/(core abstraction dùng chung),torch/csrc/(C++ binding giữa Python và C++ backend).Thực hành: Clone repo PyTorch, dùng
view/tìm kiếm để khám phá cấu trúc thư mục, ghi chú lại vai trò từng thư mục chính vào một file note cá nhân.
Ngày 176: TensorImpl - Trái Tim Của Tensor
Mục tiêu: Hiểu tensor Python thực chất là một wrapper mỏng quanh cấu trúc C++ nào.
Lý thuyết:
TensorImplchứa metadata (shape, stride, dtype, device) và con trỏ tớiStorage;Tensor(Python-facing) chỉ là handle nhẹ trỏ tớiTensorImpl- giải thích vì sao nhiều tensor có thể share cùng storage (view).Thực hành: Đọc file định nghĩa
TensorImpltrong source, vẽ sơ đồ quan hệ Tensor → TensorImpl → Storage → data buffer.
Ngày 177: Storage - Buffer Dữ Liệu Thô
Mục tiêu: Hiểu tách biệt giữa "dữ liệu" và "cách nhìn vào dữ liệu" ở mức implementation thật.
Lý thuyết:
Storagelà buffer bộ nhớ liên tục thô, không mang thông tin shape; nhiềuTensorImpl(với stride/shape khác nhau) có thể trỏ vào cùng 1Storage- đây chính là cơ chế đằng sauview()/permute()đã học ở Giai đoạn 2.Thực hành: Trong Python, tạo tensor rồi
view()/permute(), dùng.storage().data_ptr()để verify chúng thực sự share cùng vùng nhớ.
Ngày 178: Strides & Views Ở Mức C++
Mục tiêu: Củng cố hiểu biết về stride (đã học Giai đoạn 0/2) bằng cách nhìn từ góc độ implementation.
Lý thuyết: Công thức tính offset phần tử từ chỉ số đa chiều dùng stride (
offset = Σ index_i * stride_i); cách các hàmtranspose/permutechỉ đổi stride mà không đụng tới data.Thực hành: Viết hàm Python tính tay offset một phần tử bất kỳ dựa trên shape/stride cho trước, verify khớp với
tensor.storage()[offset]thực tế.
Ngày 179: Dispatcher - Cơ Chế Định Tuyến Op
Mục tiêu: Hiểu làm sao 1 lời gọi
torch.add(a, b)biết phải chạy kernel CPU hay CUDA, có cần autograd hay không.Lý thuyết: Dispatcher là hệ thống trung tâm định tuyến mỗi op call tới đúng kernel dựa trên "dispatch key" (backend: CPU/CUDA, và các layer khác như Autograd, Autocast); mô hình "boxed kernel" cho phép nhiều kernel implementation cùng đăng ký cho 1 op.
Thực hành: Đọc tài liệu/source giải thích Dispatcher, vẽ sơ đồ luồng: Python call → Dispatcher → chọn key → kernel thực thi.
Ngày 180: Dispatch Key & Autograd Key
Mục tiêu: Hiểu vì sao autograd không phải "phép màu" mà là 1 layer trong dispatcher.
Lý thuyết: Mỗi tensor có tập dispatch key (vd
CPU,Autograd); khi gọi op, dispatcher trước tiên chạy qua Autograd key (ghi lạigrad_fn, xây computation graph) rồi mới forward xuống backend key thực thi phép tính - giải thích lại từ góc nhìn implementation những gì đã học lý thuyết ở Giai đoạn 2 (Ngày 45-47).Thực hành: Đọc source một op đơn giản (vd
add) để thấy 2 lớp đăng ký kernel (CPU kernel thực thi và Autograd kernel ghi graph) tách biệt nhau thế nào.
Ngày 181: ATen - Thư Viện Tensor Cốt Lõi
Mục tiêu: Hiểu ATen là gì và vai trò của nó trong toàn hệ thống.
Lý thuyết: ATen (A TENsor library) là thư viện C++ chứa implementation thực sự của các phép toán tensor; cơ chế code generation - nhiều kernel op được sinh tự động từ file khai báo YAML (
native_functions.yaml) thay vì viết tay từng cái.Thực hành: Mở file
native_functions.yamltrong source, tìm khai báo của vài op quen thuộc (add,matmul), quan sát cách signature được định nghĩa.
Ngày 182: Đọc Kernel Thật Cho Một Op Đơn Giản
Mục tiêu: Lần đầu đọc trọn vẹn 1 đường đi từ Python API tới C++ kernel thật.
Lý thuyết: Ôn lại toàn bộ chuỗi: Python
torch.add→ Dispatcher → Autograd kernel → CPU/CUDA kernel implementation trong ATen.Thực hành: Truy vết (trace) toàn bộ đường đi của op
addqua source code (dùng tìm kiếm trong repo), viết lại thành 1 sơ đồ tổng kết đầy đủ cho riêng mình - tài liệu tham chiếu quan trọng cho các ngày sau.
Ngày 183: C++ Extension - Setup Môi Trường
Mục tiêu: Chuẩn bị viết custom op C++ đầu tiên.
Lý thuyết:
torch.utils.cpp_extension- cơ chế build C++/CUDA code và bind vào Python thông quapybind11, không cần build lại toàn bộ PyTorch.Thực hành: Setup project C++ extension tối giản (1 hàm cộng 2 số) theo hướng dẫn chính thức, build và gọi được từ Python.
Ngày 184: Viết Custom Op Bằng C++ Extension
Mục tiêu: Có 1 custom op C++ thực thụ hoạt động trong PyTorch.
Lý thuyết: Cách nhận
torch::Tensorlàm tham số trong C++, thao tác dữ liệu qua con trỏ raw hoặc accessor, trả vềtorch::Tensormới.Thực hành: Viết custom op C++ tính một phép biến đổi đơn giản trên CPU (vd elementwise square), bind qua
pybind11, so sánh output với phiên bản PyTorch thuần.
Ngày 185: Custom Op - Thêm Backward Bằng C++
Mục tiêu: Custom op có thể tham gia đầy đủ vào autograd graph.
Lý thuyết: Đăng ký cả forward và backward kernel cho custom op để nó tương thích với
.backward()của PyTorch.Thực hành: Mở rộng custom op Ngày 184 để có backward, verify bằng
torch.autograd.gradcheck.
Ngày 186: Custom CUDA Kernel - Cú Pháp Launch Cơ Bản
Mục tiêu: Viết dòng CUDA kernel đầu tiên, chuẩn bị nền cho Giai đoạn 9.
Lý thuyết:
__global__function, cấu trúc launchkernel<<<blocks, threads>>>(...),threadIdx/blockIdx/blockDimđể mỗi thread biết mình xử lý phần tử nào.Thực hành: Viết kernel CUDA "hello world" (mỗi thread in ra id của mình), biên dịch bằng
nvcc, chạy thử trên GPU.
Ngày 187: Custom CUDA Kernel - Elementwise Add
Mục tiêu: Viết kernel CUDA thực sự hữu ích đầu tiên và tích hợp vào PyTorch.
Lý thuyết: Ôn lại cách mỗi thread tính 1 phần tử của phép cộng elementwise dựa trên global index (
blockIdx.x * blockDim.x + threadIdx.x).Thực hành: Viết CUDA kernel elementwise add, bind vào PyTorch qua C++ extension (Ngày 183-185), so sánh tốc độ với
torch.addgốc trên tensor lớn.
Ngày 188: CUDA Streams & Events
Mục tiêu: Hiểu cơ chế song song hoá và đồng bộ hoá giữa các kernel launch - nền tảng cho profiling và distributed training sau này.
Lý thuyết: CUDA Stream - hàng đợi lệnh thực thi trên GPU, các stream khác nhau có thể chạy song song; Event dùng để đo thời gian hoặc đồng bộ giữa các stream.
Thực hành: Viết code chạy 2 kernel trên 2 stream khác nhau, dùng CUDA Event đo thời gian mỗi kernel, so sánh với chạy tuần tự trên cùng 1 stream.
Ngày 189: Profiling Kernel Launch Overhead
Mục tiêu: Nhận biết chi phí "ẩn" của việc launch quá nhiều kernel nhỏ - vấn đề mà torch.compile/Flash Attention giải quyết.
Lý thuyết: Mỗi lần launch kernel có overhead cố định (launch latency); nhiều phép toán nhỏ liên tiếp (như trong eager mode PyTorch) có thể bị giới hạn bởi overhead này thay vì bởi tính toán thực sự (kernel-launch-bound).
Thực hành: Dùng PyTorch Profiler đo thời gian một chuỗi nhiều op nhỏ liên tiếp trên GPU, quan sát tỉ lệ thời gian launch overhead so với compute time thực tế.
Ngày 190: Autograd Engine - Node, Edge & Execution
Mục tiêu: Hiểu implementation thật của autograd graph ở mức C++, không chỉ khái niệm.
Lý thuyết: Computation graph gồm các
Node(mỗi node là 1 hàm backward của 1 op),Edgenối các node; execution engine chạy graph theo topological order (giống thuật toán đã tự cài ở mini-autograd engine, Giai đoạn 2 Ngày 51) nhưng có hỗ trợ đa luồng.Thực hành: Đối chiếu lại engine
Valuetự viết ở Giai đoạn 2 với thiết kế Node/Edge thật của PyTorch, ghi chú điểm giống và khác.
Ngày 191: Custom Autograd Function
Mục tiêu: Biết cách "chèn" logic backward tuỳ chỉnh vào graph mà không cần viết C++.
Lý thuyết:
torch.autograd.Functionvớiforward()/backward()tĩnh,ctx.save_for_backward()để lưu tensor cần cho backward - cách chính thống để implement op có gradient tuỳ chỉnh hoàn toàn bằng Python.Thực hành: Viết một
torch.autograd.Functiontuỳ chỉnh (vd hàm activation lạ chưa có sẵn), verify gradient bằnggradcheck, dùng nó trong 1 mạng nhỏ và train thử.
Ngày 192: TorchScript - Tracing Tổng Quan
Mục tiêu: Bắt đầu tìm hiểu cách PyTorch "đóng băng" model thành dạng có thể chạy độc lập khỏi Python (quan trọng cho deployment ở Giai đoạn 10).
Lý thuyết:
torch.jit.tracechạy model 1 lần với input mẫu, ghi lại chuỗi op đã thực thi thành graph tĩnh - giống nguyên lý tracing củatf.functionđã học ở Giai đoạn 3, Ngày 78.Thực hành: Trace 1 model đơn giản bằng
torch.jit.trace, in ra graph đã sinh, so sánh khái niệm với tracing của TensorFlow.
(Còn tiếp: Ngày 193-209 - Scripting, torch.compile (Dynamo/AOTAutograd/Inductor), Triton nhập môn, Project fused kernel)
Ngày 193: TorchScript Tracing - Thực Hành & Giới Hạn
Mục tiêu: Biết khi nào tracing "phản chủ" - bẫy phổ biến nhất khi deploy model có control flow.
Lý thuyết: Tracing chỉ ghi lại đường thực thi duy nhất đã chạy - nếu model có
ifphụ thuộc vào giá trị input, graph traced sẽ "đóng cứng" nhánh đã chạy, sai với input khác đi vào nhánh kia (giống hoàn toàn vấn đề retracing/control flow đã học ở TF Ngày 78-80).Thực hành: Cố tình trace 1 model có
ifphụ thuộc input, verify model traced cho kết quả sai khi input đi vào nhánh khác nhánh lúc trace.
Ngày 194: TorchScript - Scripting
Mục tiêu: Hiểu giải pháp cho vấn đề Ngày 193.
Lý thuyết:
torch.jit.scriptphân tích trực tiếp source code Python (không chạy thử) để chuyển thành TorchScript IR, giữ nguyên được control flow động - đánh đổi là code phải viết theo subset Python được TorchScript hỗ trợ (type hint nghiêm ngặt hơn).Thực hành: Script hoá model có
ifở Ngày 193 bằngtorch.jit.script, verify kết quả đúng ở cả 2 nhánh.
Ngày 195: So Sánh Sâu Tracing vs Scripting
Mục tiêu: Có tiêu chí rõ ràng để chọn phương pháp phù hợp trong công việc thực tế.
Lý thuyết: Tổng hợp bảng so sánh: tốc độ convert, khả năng hỗ trợ control flow, mức độ Python hỗ trợ, độ khó debug khi lỗi.
Thực hành: Convert cùng 1 model (có cả phần tuyến tính và phần có control flow) bằng cả 2 cách, ghi lại trải nghiệm thực tế (lỗi gặp phải, cách sửa) làm tài liệu tham chiếu cá nhân.
Ngày 196: torch.compile - Tổng Quan & Động Lực
Mục tiêu: Hiểu vì sao PyTorch giới thiệu
torch.compiledù đã có TorchScript.Lý thuyết:
torch.compile(PyTorch 2.x) giữ được trải nghiệm eager-mode (không cần đổi cách viết code như scripting) nhưng vẫn đạt tốc độ gần với compiled graph, nhờ kiến trúc 3 tầng: Dynamo (bắt graph) → AOTAutograd (sinh graph cho cả forward+backward) → Inductor (sinh code tối ưu, thường bằng Triton).Thực hành: Chạy
torch.compile(model)trên 1 model đã có, benchmark tốc độ trước/sau ở mức tổng quan (chưa cần hiểu cơ chế trong).
Ngày 197: Dynamo - Bắt Graph Từ Bytecode Python
Mục tiêu: Hiểu tầng đầu tiên của torch.compile hoạt động thế nào.
Lý thuyết: Dynamo can thiệp vào Python bytecode ngay khi thực thi để trích xuất graph các phép toán tensor, khác hẳn tracing/scripting truyền thống; khi gặp code không thể capture (side effect phức tạp, thư viện ngoài), Dynamo tạo "graph break" - chia nhỏ thành nhiều graph con xen kẽ với Python thường.
Thực hành: Dùng
TORCH_LOGS="dynamo"hoặctorch._dynamo.explain()để xem graph mà Dynamo capture được từ 1 hàm cụ thể.
Ngày 198: Guards & Recompilation
Mục tiêu: Hiểu cơ chế đảm bảo tính đúng đắn của graph đã compile.
Lý thuyết: "Guard" - điều kiện kiểm tra (shape, dtype, giá trị một số biến) mà Dynamo gắn vào graph đã compile; nếu input mới vi phạm guard, Dynamo tự động recompile - giải thích tại sao lần chạy đầu với shape mới luôn chậm hơn.
Thực hành: Gọi model đã compile với nhiều shape input khác nhau, quan sát qua log số lần recompile xảy ra, thử dùng
dynamic=Trueđể giảm recompilation.
Ngày 199: AOTAutograd
Mục tiêu: Hiểu tầng thứ 2, nơi cả forward và backward được compile cùng lúc.
Lý thuyết: AOTAutograd chạy autograd "trước" (ahead-of-time) trên graph đã Dynamo capture để sinh ra graph backward tương ứng ngay tại thời điểm compile, thay vì để autograd engine thông thường xử lý động ở runtime - cho phép Inductor tối ưu cả 2 graph cùng lúc.
Thực hành: Đọc tài liệu/log để thấy graph forward và backward được sinh riêng biệt sau bước AOTAutograd cho 1 model đơn giản.
Ngày 200: Inductor - Backend Sinh Code
Mục tiêu: Hiểu tầng cuối cùng, nơi tốc độ thực sự đến từ đâu.
Lý thuyết: Inductor nhận graph từ AOTAutograd, thực hiện các tối ưu (op fusion - gộp nhiều op nhỏ thành 1 kernel lớn để giảm launch overhead đã học Ngày 189) rồi sinh code thực thi - trên GPU thường sinh ra Triton kernel, trên CPU sinh C++.
Thực hành: Dùng
TORCH_LOGS="output_code"để xem code Triton mà Inductor sinh ra cho 1 hàm PyTorch đơn giản, đối chiếu với kernel CUDA tự viết tay ở Ngày 187.
Ngày 201: Benchmark torch.compile Trên Model Thật
Mục tiêu: Có số liệu thực nghiệm thuyết phục về hiệu quả torch.compile.
Lý thuyết: Ôn lại toàn bộ 3 tầng Dynamo → AOTAutograd → Inductor đã học.
Thực hành: Benchmark model đã cài ở Giai đoạn 6 (GPT-mini hoặc LLaMA-block) với và không có
torch.compile, đo cả thời gian training step và inference, ghi chú lại % speedup.
Ngày 202: Debug torch.compile - Graph Break & Logging
Mục tiêu: Có kỹ năng thực tế để debug khi torch.compile không nhanh như mong đợi.
Lý thuyết: Graph break làm giảm hiệu quả tối ưu (rơi về eager mode cho đoạn đó); các biến môi trường
TORCH_LOGShữu ích (graph_breaks,recompiles) để chẩn đoán.Thực hành: Cố tình viết code gây graph break (vd gọi
.item()giữa hàm), dùng log để phát hiện, sửa lại code để loại bỏ graph break, đo lại tốc độ.
Ngày 203: Triton - Nhập Môn
Mục tiêu: Hiểu vì sao viết GPU kernel bằng Python (Triton) lại khả thi và phổ biến.
Lý thuyết: Triton là ngôn ngữ/compiler cho phép viết kernel GPU hiệu năng cao bằng cú pháp gần giống Python, tự động xử lý nhiều tối ưu bộ nhớ mà CUDA thuần phải viết tay (memory coalescing, shared memory) - chính là công nghệ đứng sau Inductor (Ngày 200) và Flash Attention (Giai đoạn 6, Ngày 156).
Thực hành: Cài đặt
triton, đọc qua ví dụ kernel mẫu trong tài liệu chính thức, chạy thử.
Ngày 204: Triton - Cú Pháp Kernel Cơ Bản
Mục tiêu: Hiểu các khối xây dựng cơ bản của một Triton kernel.
Lý thuyết:
@triton.jitdecorator,tl.program_id()(tương đươngblockIdxtrong CUDA), khái niệm block xử lý theo vector thay vì từng thread đơn lẻ như CUDA,tl.load()/tl.store()để đọc/ghi bộ nhớ.Thực hành: Đọc kỹ từng dòng của kernel mẫu (thường là vector add) trong tài liệu Triton, chú thích lại bằng tiếng Việt để chắc chắn hiểu từng phần.
Ngày 205: Viết Triton Kernel Đầu Tiên - Vector Add
Mục tiêu: Có 1 Triton kernel tự viết chạy được, so sánh với CUDA kernel đã viết tay Ngày 187.
Lý thuyết: Ôn lại cấu trúc kernel Ngày 204, cách launch kernel Triton từ Python (
kernel[grid](...)).Thực hành: Viết Triton kernel vector add, benchmark tốc độ so với CUDA kernel tự viết (Ngày 187) và với
torch.add.
Ngày 206: Đọc Code Triton Do Inductor Sinh Ra
Mục tiêu: Kết nối lý thuyết torch.compile (Ngày 200) với thực hành Triton vừa học.
Lý thuyết: Ôn lại cách xem output code Inductor (Ngày 200).
Thực hành: Lấy code Triton Inductor sinh ra cho 1 op PyTorch (vd fused elementwise), đọc và so sánh với kernel tự viết tay Ngày 205 - nhận xét Inductor tối ưu thêm gì so với bản tự viết.
Ngày 207: Project - Custom Fused Kernel Bằng Triton
Mục tiêu: Tự tối ưu một phần thực sự của model bằng kernel tự viết - kỹ năng "đọc tới tận cùng" mà lộ trình hướng tới.
Lý thuyết: Op fusion (gộp bias-add + activation thành 1 kernel) giảm số lần đọc/ghi bộ nhớ GPU so với chạy 2 op riêng biệt (liên hệ trực tiếp lý do Flash Attention nhanh, Ngày 155).
Thực hành: Viết Triton kernel fused "bias + GELU" (gộp 2 op thành 1), tích hợp vào FFN của LLaMA-block đã cài Giai đoạn 6 (Ngày 161).
Ngày 208: Profile Trước/Sau Custom Kernel
Mục tiêu: Định lượng chính xác lợi ích của việc tự viết kernel.
Lý thuyết: Ôn lại cách dùng PyTorch Profiler (Ngày 189) để đo thời gian từng op.
Thực hành: Profile forward pass của LLaMA-block trước và sau khi thay FFN bằng fused kernel Ngày 207, so sánh thời gian và số lần kernel launch, viết báo cáo ngắn tổng kết kết quả.
Ngày 209: Checkpoint & Review Giai đoạn 7
Mục tiêu: Củng cố kiến thức trước khi chuyển sang TensorFlow.
Lý thuyết: Tổng hợp lại toàn bộ chuỗi: Tensor/Storage → Dispatcher → ATen → C++/CUDA extension → Autograd engine → TorchScript → torch.compile (Dynamo/AOTAutograd/Inductor) → Triton.
Thực hành: Tự kiểm tra: vẽ lại sơ đồ đầy đủ luồng đi của 1 op từ Python xuống tận CUDA kernel không nhìn tài liệu; giải thích cho người khác vì sao
torch.compilenhanh hơn eager mode bằng đúng 3 khái niệm Dynamo/AOTAutograd/Inductor.
Checkpoint cuối Giai đoạn 7
Có thể giải thích rõ Dispatcher định tuyến 1 op call thế nào không?
Custom CUDA/Triton kernel tự viết có chạy đúng và nhanh hơn baseline không?
Có thể tự chẩn đoán graph break trong torch.compile và sửa được không?
Nếu ổn, tiếp tục sang Giai đoạn 8 - TensorFlow.
Giai Đoạn 8 - TensorFlow (Ngày 210 - 229)
Mục tiêu giai đoạn: Đối chiếu trực tiếp với những gì đã học ở Giai đoạn 7 - hiểu Graph Runtime và XLA compiler của TensorFlow, từ đó có cái nhìn so sánh sâu giữa 2 hệ sinh thái framework lớn nhất.
Ngày 210: Tổng Quan Cấu Trúc Source Code TensorFlow
Mục tiêu: Có bản đồ định hướng trước khi đọc sâu, tương tự đã làm với PyTorch ở Ngày 175.
Lý thuyết: Cấu trúc chính:
tensorflow/core/(C++ runtime),tensorflow/python/(Python binding),tensorflow/compiler/xla/(XLA compiler).Thực hành: Clone repo TensorFlow, khám phá cấu trúc thư mục, ghi chú đối chiếu với cấu trúc PyTorch đã học (
aten/,c10/,torch/csrc/).
Ngày 211: GraphDef - Biểu Diễn Graph Bằng Protobuf
Mục tiêu: Hiểu cách TF serialize một computation graph thành dữ liệu có thể lưu/truyền.
Lý thuyết:
GraphDeflà biểu diễn protobuf của toàn bộ graph (danh sách Node và kết nối giữa chúng); đây là format graph tĩnh gốc từ TF1, vẫn là nền tảng bên dướitf.functionở TF2.Thực hành: Lấy
ConcreteFunctiontừ 1 hàm@tf.functionđã viết ở Giai đoạn 3, in raGraphDeftương ứng, quan sát cấu trúc Node.
Ngày 212: Node & Op Trong Graph
Mục tiêu: Hiểu đơn vị nhỏ nhất của graph TF.
Lý thuyết: Mỗi
NodetrongGraphDeftương ứng 1 lần gọiOpcụ thể (vdAdd,MatMul) kèm attribute (dtype, shape...) và danh sách input node; phân biệtOp(định nghĩa trừu tượng) vàKernel(implementation cụ thể trên 1 device).Thực hành: Duyệt qua các Node trong
GraphDefNgày 211, liệt kê các Op xuất hiện và input/output của từng node.
Ngày 213: Cơ Chế Đăng Ký Op & Kernel
Mục tiêu: Hiểu cách TF biết chạy kernel nào cho 1 Op trên 1 device cụ thể - so sánh trực tiếp với Dispatcher của PyTorch (Giai đoạn 7, Ngày 179).
Lý thuyết:
REGISTER_OP(khai báo interface trừu tượng của Op) vàREGISTER_KERNEL_BUILDER(đăng ký implementation cụ thể cho từng device/dtype) - mỗi Op có thể có nhiều kernel ứng với CPU/GPU khác nhau, tương tự cách ATen đăng ký nhiều backend cho 1 op.Thực hành: Tìm trong source code khai báo
REGISTER_OPvàREGISTER_KERNEL_BUILDERcho opAdd, đối chiếu với cách ATen đăng ký opaddđã đọc ở Giai đoạn 7 (Ngày 182) - lập bảng so sánh cơ chế 2 bên.
Ngày 214: Đọc Kernel Thật Cho Một Op TF
Mục tiêu: Có trải nghiệm đọc source thực tế tương đương đã làm với PyTorch.
Lý thuyết: Ôn lại chuỗi: Python API → Op registration → Kernel implementation.
Thực hành: Đọc trọn vẹn implementation kernel CPU của 1 op đơn giản trong source TF, viết tóm tắt so sánh độ phức tạp/phong cách code với kernel ATen đã đọc ở PyTorch.
Ngày 215: TF Executor - Lập Lịch Thực Thi Graph
Mục tiêu: Hiểu graph được "chạy" thế nào sau khi đã xây xong.
Lý thuyết: Executor duyệt graph, xác định node nào sẵn sàng chạy (đã có đủ input), lập lịch thực thi - có thể chạy song song các node độc lập nhau.
Thực hành: Vẽ sơ đồ 1 graph nhỏ có nhánh song song (2 op không phụ thuộc nhau), phân tích Executor có thể chạy chúng đồng thời thế nào.
Ngày 216: Device Placement
Mục tiêu: Hiểu cách TF quyết định 1 op chạy trên CPU hay GPU nào.
Lý thuyết: Device placement tự động dựa trên heuristic (ưu tiên GPU nếu có kernel GPU) hoặc chỉ định thủ công bằng
tf.device(); chi phí ẩn khi dữ liệu phải copy qua lại giữa device khác nhau liên tục.Thực hành: Dùng
tf.debugging.set_log_device_placement(True)để xem TF đặt từng op ở device nào, thử ép 1 phần graph chạy CPU giữa các op GPU để quan sát overhead copy dữ liệu.
Ngày 217: Kernel Execution & Runtime Dispatch
Mục tiêu: Hoàn thiện bức tranh runtime execution của TF.
Lý thuyết: Sau khi Executor chọn node và device đã được placement, runtime dispatch tới đúng kernel đã đăng ký (Ngày 213) để thực thi thực sự.
Thực hành: Tổng hợp lại toàn bộ luồng Ngày 211-217 thành 1 sơ đồ hoàn chỉnh: GraphDef → Node/Op → Executor lập lịch → Device Placement → Kernel Dispatch → thực thi.
Ngày 218: XLA - Tổng Quan & Động Lực
Mục tiêu: Hiểu vì sao TF cần thêm 1 compiler riêng (XLA) bên cạnh graph runtime thông thường.
Lý thuyết: Graph runtime thông thường thực thi từng op riêng lẻ (tương tự "eager-ish" dù là graph) - XLA (Accelerated Linear Algebra) compile toàn bộ 1 đoạn graph thành 1 chương trình máy tối ưu, cho phép fusion xuyên op mà runtime thông thường không làm được - động lực giống hệt Inductor của PyTorch (Giai đoạn 7, Ngày 200).
Thực hành: Đọc tài liệu chính thức về XLA, tóm tắt (bằng lời riêng) 3 lợi ích chính XLA mang lại.
Ngày 219: HLO - Intermediate Representation Của XLA
Mục tiêu: Hiểu ngôn ngữ trung gian mà XLA làm việc trên đó.
Lý thuyết: HLO (High Level Optimizer IR) là biểu diễn trung gian độc lập phần cứng mà graph TF được lower xuống trước khi tối ưu - tương tự vai trò của graph mà AOTAutograd sinh ra trước khi đưa cho Inductor (Giai đoạn 7, Ngày 199-200).
Thực hành: Bật
jit_compile=Truecho 1tf.function, dùng biến môi trường debug XLA để dump HLO IR ra file text, đọc và đối chiếu với GraphDef gốc.
Ngày 220: XLA Compiler Pipeline
Mục tiêu: Hiểu các giai đoạn HLO đi qua để trở thành machine code thực thi.
Lý thuyết: Pipeline gồm nhiều pass tối ưu trên HLO (constant folding, fusion, layout assignment) trước khi lower xuống code máy cụ thể cho từng backend (LLVM cho CPU, PTX cho GPU).
Thực hành: Vẽ sơ đồ pipeline XLA từ HLO thô tới code máy, chú thích các pass tối ưu chính đã đọc được.
Ngày 221: Fusion Trong XLA
Mục tiêu: Hiểu kỹ thuật tối ưu quan trọng nhất của XLA, so sánh trực tiếp với Inductor fusion đã học.
Lý thuyết: XLA gộp nhiều op liên tiếp (elementwise, reduction) thành 1 "fusion kernel" duy nhất để giảm số lần đọc/ghi bộ nhớ - cùng nguyên lý với op fusion của Inductor (Giai đoạn 7) và ý tưởng nền tảng của Flash Attention (Giai đoạn 6).
Thực hành: So sánh HLO trước/sau fusion cho 1 đoạn tính toán có nhiều op elementwise liên tiếp, đếm số kernel trước và sau khi XLA fusion.
Ngày 222: Sử Dụng jit_compile Thực Tế & Benchmark
Mục tiêu: Đo lường lợi ích thực sự của XLA trên model cụ thể.
Lý thuyết: Ôn lại cách bật XLA (
tf.function(jit_compile=True)), một số hạn chế (yêu cầu shape ổn định hơn, một số op chưa hỗ trợ XLA).Thực hành: Benchmark model TF đã xây ở Giai đoạn 3 (Ngày 96) với và không có XLA, so sánh với kết quả
torch.compileđã đo ở Giai đoạn 7 (Ngày 201) trên bài toán tương đương.
Ngày 223: XLA Trên TPU vs GPU
Mục tiêu: Hiểu XLA đóng vai trò cầu nối quan trọng thế nào cho TPU.
Lý thuyết: TPU chỉ chạy được thông qua chương trình đã compile bằng XLA (không có chế độ "eager kernel-by-kernel" như GPU) - đây là lý do TF/JAX có lợi thế lịch sử trên TPU; ôn lại kiến trúc TPU đã giới thiệu sơ lược ở Giai đoạn 3 (Ngày 95).
Thực hành: Đọc so sánh hiệu năng XLA trên GPU vs TPU cho cùng 1 loại model, ghi chú lại các ràng buộc khác biệt (vd TPU yêu cầu static shape nghiêm ngặt hơn).
Ngày 224: Custom TF Op - Viết Bằng C++
Mục tiêu: Tự tay đăng ký 1 Op mới vào TF, tương tự đã làm với PyTorch C++ extension ở Giai đoạn 7.
Lý thuyết: Ôn lại
REGISTER_OP/REGISTER_KERNEL_BUILDER(Ngày 213), cách viết class kernel kế thừaOpKernelvới hàmCompute().Thực hành: Viết custom Op C++ đơn giản (vd elementwise square, giống bài đã làm với PyTorch), build bằng hướng dẫn chính thức của TF.
Ngày 225: Build & Sử Dụng Custom Op Từ Python
Mục tiêu: Hoàn thiện vòng đời custom op, gọi được từ Python giống 1 op TF bình thường.
Lý thuyết: Cách load shared library (
.so) chứa custom op vào Python quatf.load_op_library.Thực hành: Build custom op Ngày 224 thành
.so, load và gọi từ Python, verify output đúng, so sánh trải nghiệm với việc build C++ extension cho PyTorch (Giai đoạn 7).
Ngày 226: So Sánh Toàn Diện PyTorch vs TensorFlow
Mục tiêu: Tổng hợp toàn bộ 2 giai đoạn thành 1 tài liệu tham chiếu có giá trị lâu dài.
Lý thuyết: Đối chiếu song song: Dispatcher (PyTorch) ↔ Op/Kernel Registration (TF); ATen ↔ core kernel; torch.compile (Dynamo/AOTAutograd/Inductor) ↔ tf.function + XLA (Tracing/AutoGraph + HLO pipeline); TorchScript ↔ GraphDef.
Thực hành: Viết 1 bảng so sánh chi tiết đầy đủ (định dạng markdown), lưu lại làm tài liệu tham chiếu cho công việc sau này.
Ngày 227: Project - Profile TF Model Với/Không XLA & Custom Op
Mục tiêu: Có project thực chiến chứng minh hiểu biết TF.
Lý thuyết: Ôn lại TensorFlow Profiler (sẽ đào sâu thêm ở Giai đoạn 9).
Thực hành: Lấy model CIFAR-10 TF đã xây (Giai đoạn 3, Ngày 96), tích hợp custom op Ngày 225 vào, profile với/không XLA, viết báo cáo ngắn tổng kết kết quả đo được.
Ngày 228: Hoàn Thiện Tài Liệu So Sánh PyTorch vs TensorFlow
Mục tiêu: Có 1 tài liệu chất lượng cao thể hiện độ hiểu biết sâu cả 2 framework - hữu ích khi phỏng vấn hoặc chia sẻ kiến thức.
Lý thuyết: Ôn lại toàn bộ Giai đoạn 2, 3, 7, 8.
Thực hành: Hoàn thiện tài liệu so sánh Ngày 226 thành bản đầy đủ, bao gồm cả phần API-level (Giai đoạn 2-3) và-level (Giai đoạn 7-8), có ví dụ code minh hoạ cho mỗi điểm so sánh.
Ngày 229: Checkpoint & Review Giai đoạn 8
Mục tiêu: Củng cố trước khi bước sang phần GPU & Distributed Training - nơi kiến thức của cả 2 giai đoạn 7-8 sẽ được vận dụng trực tiếp.
Lý thuyết: Tổng hợp lại: GraphDef/Node/Op → Op Registration → Executor/Device Placement → XLA (HLO → Fusion → Compiler Pipeline).
Thực hành: Tự kiểm tra: giải thích XLA fusion hoạt động thế nào và tại sao nó giống Inductor fusion của PyTorch, không nhìn tài liệu.
Checkpoint cuối Giai đoạn 8
Có thể vẽ sơ đồ đầy đủ luồng thực thi 1 op TF từ Python tới kernel thật không?
Hiểu rõ vai trò của XLA và HLO trong việc tối ưu graph không?
Tài liệu so sánh PyTorch vs TensorFlow đã đủ chi tiết để dùng làm tham chiếu lâu dài chưa?
Nếu ổn, tiếp tục sang Giai đoạn 9 - GPU & Distributed Training.
Giai Đoạn 9 - GPU & Distributed Training (Ngày 230 - 264)
Mục tiêu giai đoạn: Hiểu kiến trúc GPU ở mức phần cứng, cơ chế truyền thông giữa nhiều GPU (NCCL), các chiến lược song song hoá training (Data/Tensor/Pipeline/Sequence Parallel), mixed precision, và kỹ năng debug training ở quy mô lớn.
Ngày 230: Kiến Trúc GPU - SM & CUDA Core
Mục tiêu: Hiểu đơn vị tính toán cơ bản của GPU trước khi tối ưu bất cứ điều gì.
Lý thuyết: Streaming Multiprocessor (SM) - đơn vị xử lý độc lập trên GPU, mỗi SM chứa nhiều CUDA core; khác biệt căn bản kiến trúc GPU (nhiều core đơn giản, tính toán song song khối lượng lớn - SIMD/SIMT) so với CPU (ít core mạnh, tối ưu cho tác vụ tuần tự phức tạp).
Thực hành: Tra cứu thông số SM/CUDA core của GPU đang dùng (
nvidia-smihoặc tài liệu hãng), vẽ sơ đồ đơn giản kiến trúc GPU đó.
Ngày 231: Warp & Mô Hình Thực Thi Thread
Mục tiêu: Hiểu đơn vị lập lịch thực tế trên GPU - không phải từng thread riêng lẻ.
Lý thuyết: Warp - nhóm 32 thread thực thi đồng bộ theo mô hình SIMT (Single Instruction Multiple Thread); warp divergence xảy ra khi các thread trong cùng warp đi vào nhánh
if/elsekhác nhau, làm giảm hiệu năng do phải serialize.Thực hành: Viết kernel CUDA (ôn lại Giai đoạn 7, Ngày 186-187) có
ifphụ thuộcthreadIdxgây warp divergence, benchmark so với kernel không có divergence.
Ngày 232: Block, Grid & Occupancy
Mục tiêu: Hiểu cách tổ chức hàng nghìn thread thành cấu trúc quản lý được.
Lý thuyết: Block (nhóm thread chạy trên cùng 1 SM, có thể chia sẻ shared memory) và Grid (tập hợp các block); Occupancy - tỉ lệ warp đang hoạt động so với khả năng tối đa của SM, occupancy thấp có thể khiến GPU không được tận dụng hết.
Thực hành: Thử launch cùng 1 kernel với các cấu hình block size khác nhau (32, 128, 256, 1024 thread/block), đo thời gian chạy và giải thích kết quả qua khái niệm occupancy.
Ngày 233: Memory Hierarchy - Global, Shared, Register
Mục tiêu: Hiểu tại sao vị trí lưu dữ liệu ảnh hưởng tốc độ hàng chục-hàng trăm lần - nền tảng để hiểu lại Flash Attention từ Giai đoạn 6 ở mức sâu hơn.
Lý thuyết: Global memory (HBM - lớn nhưng chậm), Shared memory (SRAM trên mỗi SM - nhỏ nhưng nhanh hơn nhiều), Register (nhanh nhất, riêng cho mỗi thread); đây chính xác là "SRAM vs HBM" đã nhắc tới ở Giai đoạn 6 (Ngày 155) khi học động lực của Flash Attention.
Thực hành: Đọc lại phần lý thuyết Flash Attention (Giai đoạn 6, Ngày 155-156) và giải thích lại bằng ngôn ngữ phần cứng vừa học - tự viết đoạn giải thích hoàn chỉnh "vì sao Flash Attention nhanh" chỉ dùng khái niệm SM/Warp/Memory Hierarchy.
Ngày 234: Memory Coalescing & Bank Conflict
Mục tiêu: Học kỹ thuật tối ưu truy cập bộ nhớ thực tế khi viết kernel.
Lý thuyết: Memory coalescing - khi các thread trong 1 warp truy cập vùng nhớ liên tục, phần cứng gộp thành 1 giao dịch bộ nhớ duy nhất (nhanh hơn nhiều so với truy cập rời rạc); bank conflict trong shared memory khi nhiều thread truy cập cùng bank cùng lúc.
Thực hành: Viết 2 phiên bản kernel đọc dữ liệu - 1 bản coalesced (truy cập liên tục) và 1 bản strided (truy cập nhảy cóc), benchmark so sánh tốc độ.
Ngày 235: Tối Ưu Occupancy Thực Tế
Mục tiêu: Áp dụng kiến thức Ngày 230-234 vào việc tối ưu 1 kernel thực tế.
Lý thuyết: Đánh đổi giữa số register/shared memory dùng mỗi thread và số thread có thể chạy đồng thời trên 1 SM (dùng nhiều register hơn → occupancy thấp hơn nhưng mỗi thread nhanh hơn).
Thực hành: Dùng công cụ
nvidia-nsight-compute(hoặc PyTorch Profiler) để phân tích occupancy của kernel Triton đã viết ở Giai đoạn 7 (Ngày 205/207), thử điều chỉnh block size để cải thiện.
Ngày 236: NCCL - Tổng Quan
Mục tiêu: Hiểu vì sao cần một thư viện chuyên biệt cho giao tiếp giữa nhiều GPU.
Lý thuyết: NCCL (NVIDIA Collective Communications Library) tối ưu các thao tác giao tiếp tập thể (collective communication) giữa nhiều GPU/nhiều máy, tận dụng NVLink/InfiniBand để đạt băng thông cao - nền tảng bắt buộc cho mọi hình thức distributed training.
Thực hành: Đọc tài liệu NCCL, liệt kê các thao tác collective chính (AllReduce, Broadcast, AllGather, ReduceScatter) và mục đích sử dụng của từng loại.
Ngày 237: Ring AllReduce - Thuật Toán Chi Tiết
Mục tiêu: Hiểu thuật toán quan trọng nhất cho việc đồng bộ gradient trong Data Parallel training.
Lý thuyết: Ring AllReduce sắp xếp các GPU thành 1 vòng, chia dữ liệu thành nhiều chunk, mỗi bước chuyển 1 chunk sang GPU kế tiếp và cộng dồn - đạt băng thông hiệu quả gần tối ưu (không phụ thuộc số lượng GPU như thuật toán AllReduce ngây thơ dùng 1 GPU trung tâm).
Thực hành: Vẽ tay từng bước Ring AllReduce cho 4 GPU với dữ liệu giả định, verify kết quả cuối cùng mỗi GPU có đúng tổng của tất cả GPU.
Ngày 238: Broadcast, Reduce, AllGather, ReduceScatter
Mục tiêu: Phân biệt rõ các collective primitive khác, dùng ở các phần khác nhau của distributed training (FSDP sẽ dùng AllGather/ReduceScatter thay vì AllReduce thuần).
Lý thuyết: Broadcast (1 GPU gửi tới tất cả), Reduce (gộp về 1 GPU), AllGather (mỗi GPU nhận đủ dữ liệu từ tất cả), ReduceScatter (kết hợp reduce + chia đều kết quả) - các khối xây dựng cho FSDP/ZeRO sẽ học ở các ngày sau.
Thực hành: Vẽ sơ đồ minh hoạ cho cả 4 primitive với 4 GPU, ghi chú rõ input/output của mỗi GPU trước/sau.
Ngày 239: Benchmark NCCL
Mục tiêu: Có số liệu thực tế về băng thông/độ trễ giao tiếp GPU trên phần cứng đang dùng.
Lý thuyết: Ôn lại khái niệm bandwidth vs latency, ảnh hưởng của kích thước message tới hiệu quả collective op.
Thực hành: Dùng
nccl-tests(nếu có nhiều GPU) hoặctorch.distributedbenchmark script đo AllReduce bandwidth với các kích thước tensor khác nhau; nếu chỉ có 1 GPU, đọc benchmark công khai của các cấu hình phổ biến để tham chiếu.
Ngày 240: DDP - DistributedDataParallel
Mục tiêu: Hiểu chiến lược song song hoá cơ bản và phổ biến nhất.
Lý thuyết: Data Parallelism - mỗi GPU giữ 1 bản sao đầy đủ model, xử lý 1 phần khác nhau của batch, sau đó đồng bộ gradient bằng AllReduce (Ngày 237) trước khi mỗi GPU tự cập nhật optimizer step giống nhau.
Thực hành: Đọc tài liệu
torch.nn.parallel.DistributedDataParallel, vẽ sơ đồ luồng dữ liệu 1 training step với DDP trên 4 GPU.
Ngày 241: Chạy DDP Training Script
Mục tiêu: Có kinh nghiệm thực chiến chạy training multi-GPU, không chỉ lý thuyết.
Lý thuyết: Ôn lại
DistributedSamplerđã học ở Giai đoạn 2 (Ngày 63), cách khởi tạo process group (torch.distributed.init_process_group),torchrunđể launch nhiều process.Thực hành: Chuyển training script Giai đoạn 2 (Ngày 74) sang chạy DDP multi-GPU (hoặc mô phỏng multi-process trên 1 GPU nếu hạn chế phần cứng), verify loss hội tụ giống bản single-GPU.
Ngày 242: DDP - Gradient Bucketing
Mục tiêu: Hiểu tối ưu quan trọng giúp DDP hiệu quả trong thực tế, không chỉ đúng về mặt lý thuyết.
Lý thuyết: DDP không đợi tính xong toàn bộ gradient rồi mới AllReduce - nó gộp gradient thành các "bucket" và bắt đầu AllReduce ngay khi 1 bucket sẵn sàng, chồng lấp (overlap) communication với computation của backward pass còn lại.
Thực hành: Dùng PyTorch Profiler quan sát timeline của 1 DDP training step, xác định phần AllReduce có thực sự overlap với backward compute không.
Ngày 243: FSDP - Fully Sharded Data Parallel
Mục tiêu: Hiểu chiến lược giải quyết giới hạn lớn nhất của DDP: mỗi GPU vẫn phải giữ toàn bộ model.
Lý thuyết: FSDP sharding (chia nhỏ) cả trọng số, gradient, và optimizer state ra nhiều GPU thay vì duplicate toàn bộ như DDP; mỗi GPU chỉ giữ 1 phần, dùng AllGather để lấy đủ trọng số cần khi tính forward/backward cho từng layer, rồi giải phóng ngay sau đó.
Thực hành: Vẽ sơ đồ so sánh bộ nhớ sử dụng của DDP (duplicate toàn bộ) vs FSDP (sharded) cho model có N tham số trên K GPU.
Ngày 244: FSDP - Sharding Strategy Thực Hành
Mục tiêu: Có kinh nghiệm thực tế cấu hình FSDP.
Lý thuyết: Các chiến lược sharding (
FULL_SHARD,SHARD_GRAD_OP,NO_SHARD), wrapping policy (chọn layer nào được shard riêng).Thực hành: Chuyển training script DDP Ngày 241 sang dùng FSDP, đo VRAM sử dụng trên mỗi GPU so với DDP ở cùng model size.
Ngày 245: ZeRO - Zero Redundancy Optimizer
Mục tiêu: Hiểu ý tưởng gốc mà FSDP lấy cảm hứng, từ hệ sinh thái DeepSpeed.
Lý thuyết: ZeRO Stage 1 (shard optimizer state), Stage 2 (thêm shard gradient), Stage 3 (thêm shard cả trọng số - tương đương FSDP full shard); mỗi stage giảm thêm bộ nhớ nhưng tăng thêm communication.
Thực hành: Lập bảng so sánh bộ nhớ tiết kiệm được và overhead communication tăng thêm qua từng ZeRO stage cho 1 model kích thước cụ thể.
Ngày 246: Thực Hành FSDP/DeepSpeed ZeRO & So Sánh Bộ Nhớ
Mục tiêu: Có số liệu thực nghiệm rõ ràng về hiệu quả các kỹ thuật sharding.
Lý thuyết: Ôn lại toàn bộ Ngày 243-245.
Thực hành: Train cùng 1 model (kích thước đủ lớn để thấy khác biệt) bằng DDP, FSDP, và DeepSpeed ZeRO (nếu có điều kiện cài đặt), lập bảng so sánh VRAM peak sử dụng và tốc độ training của cả 3.
Ngày 247: Tensor Parallelism - Megatron-LM Style
Mục tiêu: Hiểu chiến lược song song hoá khác hẳn Data Parallel - chia nhỏ chính phép tính bên trong 1 layer.
Lý thuyết: Thay vì mỗi GPU giữ toàn bộ layer, Tensor Parallelism chia ma trận trọng số của 1 layer Linear ra nhiều GPU (chia theo cột hoặc theo hàng), mỗi GPU tính 1 phần phép nhân ma trận rồi kết hợp lại bằng AllReduce/AllGather - cần thiết khi 1 layer đơn lẻ đã quá lớn để vừa 1 GPU.
Thực hành: Vẽ sơ đồ chia 1 phép nhân ma trận
Y = XWthành 2 phần trên 2 GPU (column-parallel), chỉ ra bước nào cần AllReduce để có kết quả đúng.
(Còn tiếp: Ngày 248-264 - Implement Tensor Parallel, Pipeline Parallel, Sequence Parallel, Mixed Precision sâu, Debug training, Profiling, Project multi-GPU)
Ngày 248: Implement Tensor Parallel Linear Layer
Mục tiêu: Biến lý thuyết Ngày 247 thành code chạy thực tế trên 2 GPU.
Lý thuyết: Ôn lại column-parallel (chia theo cột output) và row-parallel (chia theo hàng input) Linear layer, và khi nào cần AllReduce ở mỗi loại.
Thực hành: Implement
ColumnParallelLinearvàRowParallelLinearbằngtorch.distributed, verify kết quả forward/backward khớp với Linear layer thường chạy trên 1 GPU.
Ngày 249: Pipeline Parallelism - Chia Layer Theo Chiều Sâu
Mục tiêu: Hiểu chiến lược song song hoá thứ 3, chia model theo layer thay vì theo tham số hay theo batch.
Lý thuyết: Mỗi GPU giữ 1 nhóm layer liên tiếp (1 "stage"), dữ liệu chảy tuần tự qua các GPU như dây chuyền sản xuất; micro-batching - chia batch lớn thành nhiều micro-batch để các GPU có thể xử lý gối đầu nhau thay vì GPU sau phải chờ GPU trước xong hoàn toàn.
Thực hành: Vẽ sơ đồ pipeline 4-stage xử lý 4 micro-batch theo thời gian, thể hiện rõ giai đoạn nào các GPU chạy song song.
Ngày 250: Pipeline Bubble & Lịch Trình GPipe vs PipeDream
Mục tiêu: Hiểu vấn đề hiệu năng cố hữu của pipeline parallelism và các giải pháp.
Lý thuyết: "Bubble" - thời gian GPU đầu/cuối pipeline phải chờ (idle) trong lúc warm-up/cool-down của pipeline; GPipe (lịch trình đơn giản, đợi tất cả micro-batch forward xong mới backward) vs PipeDream (lịch trình 1F1B - xen kẽ forward/backward sớm hơn để giảm bubble).
Thực hành: Tính toán tỉ lệ bubble time cho pipeline GPipe với số stage và số micro-batch cho trước, so sánh với lý thuyết bubble ratio của 1F1B.
Ngày 251: Sequence Parallelism
Mục tiêu: Hiểu chiến lược song song hoá thứ 4, bổ sung cho Tensor Parallel ở những phần không chia được tốt theo tensor (như LayerNorm, Dropout).
Lý thuyết: Chia hoạt động dọc theo chiều sequence length thay vì chiều hidden dimension, giảm thêm bộ nhớ activation cho các op mà Tensor Parallel không tối ưu được hiệu quả.
Thực hành: Đọc kiến trúc Sequence Parallel kết hợp với Tensor Parallel trong Megatron-LM, vẽ sơ đồ luồng dữ liệu chuyển đổi giữa 2 chế độ song song trong 1 block Transformer.
Ngày 252: 3D Parallelism - Kết Hợp Data + Tensor + Pipeline
Mục tiêu: Có bức tranh tổng thể cách các LLM khổng lồ (hàng trăm tỷ tham số) thực sự được train.
Lý thuyết: Training model cực lớn kết hợp cả 3 (hoặc 4 với Sequence Parallel) chiến lược song song hoá cùng lúc - vd Data Parallel giữa các nhóm GPU, Tensor Parallel trong 1 node, Pipeline Parallel giữa các node; đây là lý do cấu hình cluster training LLM luôn được thiết kế theo topology phân cấp.
Thực hành: Vẽ sơ đồ topology 3D Parallelism cho 1 cluster giả định (vd 64 GPU chia thành 8 pipeline stage × 4 tensor-parallel × 2 data-parallel), giải thích luồng communication ở mỗi chiều.
Ngày 253: Mixed Precision - FP16 Mechanics Sâu
Mục tiêu: Hiểu chi tiết cách
GradScalerhoạt động bên trong, không chỉ gọi API.Lý thuyết: FP16 có dải giá trị hẹp hơn FP32 nhiều, dễ gây underflow gradient (giá trị nhỏ về 0);
GradScalernhân loss với 1 hệ số lớn trước backward để "đẩy" gradient ra khỏi vùng underflow, rồi chia lại trước khi update - tự động điều chỉnh hệ số scale dựa trên việc có phát hiện Inf/NaN hay không.Thực hành: Đọc source code
torch.cuda.amp.GradScaler, viết lại logic scale/unscale/update-scale-factor bằng tay (giả lập, không cần chạy CUDA thật) để hiểu thuật toán.
Ngày 254: BF16 vs FP16 - Dải Giá Trị & Ứng Dụng
Mục tiêu: Biết chọn đúng định dạng số cho từng tình huống - kiến thức thực dụng khi train LLM.
Lý thuyết: BF16 có cùng số bit exponent với FP32 (dải giá trị rộng như FP32) nhưng ít bit mantissa hơn (độ chính xác thấp hơn FP16) - ít bị overflow/underflow hơn FP16 nên thường không cần GradScaler khi dùng BF16; đây là lý do hầu hết LLM hiện đại (LLaMA, Mistral...) train bằng BF16.
Thực hành: So sánh dải giá trị biểu diễn được của FP32/FP16/BF16 bằng bảng số cụ thể, thử train GPT-mini (Giai đoạn 6) bằng cả FP16 và BF16, quan sát tần suất Inf/NaN xuất hiện.
Ngày 255: Debug Mixed Precision - Loss Scaling Issues
Mục tiêu: Có kỹ năng xử lý thực tế khi mixed precision gây lỗi training.
Lý thuyết: Các dấu hiệu thường gặp: loss đột nhiên thành NaN,
GradScalerliên tục giảm scale factor về rất nhỏ (dấu hiệu overflow liên tục) - nguyên nhân thường do learning rate quá cao hoặc kiến trúc có phép toán nhạy cảm (vd softmax) chạy ở FP16 thay vì FP32.Thực hành: Cố tình gây lỗi mixed precision (learning rate rất cao + FP16), quan sát log scale factor giảm dần, sửa bằng cách ép các op nhạy cảm chạy FP32 trong khối
autocast(dùngautocast(enabled=False)cục bộ).
Ngày 256: Gradient Checkpointing/Activation Recomputation
Mục tiêu: Hiểu kỹ thuật đánh đổi compute lấy bộ nhớ - công cụ quan trọng để train model lớn hơn VRAM cho phép.
Lý thuyết: Bình thường, toàn bộ activation trung gian của forward pass phải lưu lại để dùng cho backward; gradient checkpointing chỉ lưu 1 số ít "checkpoint" activation, các activation còn lại được tính lại (recompute) trong lúc backward khi cần - giảm mạnh bộ nhớ activation đổi lấy tăng thêm ~30% thời gian compute.
Thực hành: Bật
torch.utils.checkpointcho LLaMA-block (Giai đoạn 6), đo VRAM sử dụng và thời gian training có/không có gradient checkpointing trên cùng batch size.
Ngày 257: Debug Training Instability - Phát Hiện NaN/Inf
Mục tiêu: Có quy trình hệ thống để phát hiện sớm training bị hỏng, thay vì phát hiện muộn sau nhiều giờ train lãng phí.
Lý thuyết: Các vị trí thường phát sinh NaN/Inf (loss, gradient, trọng số sau update); công cụ
torch.autograd.set_detect_anomaly(True)để tự động dừng và chỉ ra chính xác op nào gây NaN trong backward.Thực hành: Cố tình gây NaN (vd chia cho 0 trong 1 custom loss), dùng
detect_anomalyđể định vị chính xác vị trí lỗi, viết hàm helper kiểm tra NaN/Inf tự động sau mỗi training step để tích hợp vào training loop chuẩn.
Ngày 258: Debug Loss Spikes - Nguyên Nhân & Cách Xử Lý
Mục tiêu: Biết chẩn đoán và xử lý hiện tượng loss đột ngột tăng vọt giữa quá trình train dài - vấn đề kinh điển khi pretrain LLM.
Lý thuyết: Nguyên nhân thường gặp: learning rate quá cao ở 1 giai đoạn cụ thể, batch dữ liệu có outlier/corrupt data, gradient explosion tích luỹ; giải pháp: gradient clipping (đã học Giai đoạn 2, Ngày 71) mạnh hơn, learning rate warmup dài hơn, hoặc rollback về checkpoint trước spike và skip batch gây lỗi.
Thực hành: Thực nghiệm gây loss spike (chèn 1 batch dữ liệu outlier cực đoan vào giữa training), quan sát ảnh hưởng, áp dụng gradient clipping để giảm thiểu tác động.
Ngày 259: PyTorch Profiler - Phân Tích Trace Sâu
Mục tiêu: Thành thạo công cụ profiling quan trọng nhất để tối ưu training thực tế.
Lý thuyết:
torch.profilerghi lại trace chi tiết (CPU ops, CUDA kernel, memory) có thể xem trực quan trong TensorBoard hoặc Chrome trace viewer; cách đọc timeline để phân biệt bottleneck do compute, do data loading, hay do communication (nếu multi-GPU).Thực hành: Profile toàn bộ training loop multi-GPU đã xây (Ngày 241/244), xác định chính xác bottleneck lớn nhất hiện tại (data loading chậm? GPU idle chờ communication? kernel launch overhead?).
Ngày 260: TensorBoard Profiler (Phía TensorFlow)
Mục tiêu: Có kỹ năng profiling tương đương ở phía TensorFlow.
Lý thuyết: TensorFlow Profiler tích hợp trong TensorBoard, cung cấp các view tương tự (trace viewer, input pipeline analyzer - đặc biệt hữu ích để phát hiện bottleneck tf.data đã học ở Giai đoạn 3).
Thực hành: Profile model TF đã xây ở Giai đoạn 3/8, dùng Input Pipeline Analyzer để xác định pipeline tf.data có đang là bottleneck hay không.
Ngày 261: Advanced Triton Kernel - Bài Tập Mini Flash Attention
Mục tiêu: Vận dụng toàn bộ kiến thức GPU (Warp, Memory Hierarchy, Occupancy) đã học trong giai đoạn này vào 1 kernel phức tạp hơn.
Lý thuyết: Ôn lại nguyên lý tiling và online softmax của Flash Attention (Giai đoạn 6, Ngày 155-156) qua lăng kính phần cứng đã học (Ngày 233-235).
Thực hành: Viết 1 phiên bản Flash Attention tối giản bằng Triton (chỉ cần đúng về mặt thuật toán, không cần tối ưu bằng bản chính thức), so sánh output với attention chuẩn đã cài (Giai đoạn 6, Ngày 131) và benchmark tốc độ/bộ nhớ trên chuỗi dài.
Ngày 262: Project - Multi-GPU Training LLaMA-mini Với FSDP + Mixed Precision
Mục tiêu: Tổng hợp phần lớn kiến thức Giai đoạn 9 vào 1 project thực chiến.
Lý thuyết: Ôn lại toàn bộ: FSDP (Ngày 243-244), BF16 mixed precision (Ngày 254), gradient checkpointing (Ngày 256).
Thực hành: Train LLaMA-block model (Giai đoạn 6, Ngày 161) ở quy mô lớn hơn bằng FSDP + BF16 + gradient checkpointing trên multi-GPU (hoặc mô phỏng nếu hạn chế phần cứng), verify loss hội tụ ổn định.
Ngày 263: Project - Profile & Tối Ưu Training
Mục tiêu: Hoàn thiện project bằng vòng lặp đo lường - tối ưu - đo lường lại, đúng quy trình 1 kỹ sư ML Infra thực thụ.
Lý thuyết: Ôn lại PyTorch Profiler (Ngày 259).
Thực hành: Profile training loop Ngày 262, xác định bottleneck, thử ít nhất 2 tối ưu cụ thể (vd tăng
num_workers, bậttorch.compileđã học Giai đoạn 7, điều chỉnh FSDP wrapping policy), đo lại và ghi nhận % cải thiện.
Ngày 264: Checkpoint & Review Giai đoạn 9
Mục tiêu: Củng cố toàn bộ kiến thức GPU/Distributed trước khi bước sang MLOps & Production.
Lý thuyết: Tổng hợp lại: kiến trúc GPU (SM/Warp/Memory) → NCCL collective ops → Data/Tensor/Pipeline/Sequence Parallel → Mixed Precision → Debug instability → Profiling.
Thực hành: Tự kiểm tra: giải thích Ring AllReduce cho người mới bằng hình vẽ; nêu rõ khi nào chọn DDP vs FSDP vs Tensor Parallel vs Pipeline Parallel cho 1 tình huống cụ thể (model size, số GPU, băng thông kết nối cho trước).
Checkpoint cuối Giai đoạn 9
Có thể giải thích rõ sự khác biệt và khi nào dùng Data/Tensor/Pipeline/Sequence Parallel không?
Project multi-GPU FSDP có train ổn định, không NaN/Inf không?
Có quy trình debug loss spike/training instability rõ ràng, tái sử dụng được cho các project sau không?
Nếu ổn, tiếp tục sang Giai đoạn 10 - MLOps & Production (giai đoạn dài thứ 2, 40 ngày).
Giai Đoạn 10 - MLOps & Production (Ngày 265 - 304)
Mục tiêu giai đoạn: Có khả năng triển khai toàn bộ vòng đời ML từ tracking thí nghiệm, versioning dữ liệu, registry model, tới serving production-grade (bao gồm serving LLM hiện đại như vLLM), hạ tầng Kubernetes, và observability.
Ngày 265: Experiment Tracking
Mục tiêu: Hiểu vấn đề thực tế mà experiment tracking giải quyết.
Lý thuyết: Khi chạy hàng chục/hàng trăm thí nghiệm (khác hyperparameter, khác data, khác kiến trúc), việc nhớ và so sánh thủ công trở nên bất khả thi; cần công cụ tự động log và so sánh.
Thực hành: Liệt kê lại tất cả thí nghiệm đã chạy từ đầu lộ trình (ước lượng), thử tưởng tượng phải so sánh chúng thủ công để cảm nhận rõ vấn đề.
Ngày 266: MLflow - Tracking API
Mục tiêu: Thành thạo công cụ experiment tracking mã nguồn mở phổ biến nhất.
Lý thuyết:
mlflow.log_param(),log_metric(),log_artifact()- cách MLflow tổ chức dữ liệu theo Experiment → Run.Thực hành: Tích hợp MLflow tracking vào training loop đã xây (Giai đoạn 9, Ngày 262), log đầy đủ hyperparameter, loss/metric theo step, và checkpoint model như artifact.
Ngày 267: MLflow UI - So Sánh Runs
Mục tiêu: Khai thác giao diện MLflow để đưa ra quyết định dựa trên dữ liệu.
Lý thuyết: MLflow UI cho phép so sánh nhiều run cạnh nhau (bảng metric, biểu đồ overlay), filter/sort theo metric.
Thực hành: Chạy 3-4 biến thể training (khác learning rate/batch size), mở MLflow UI so sánh trực quan, chọn ra cấu hình tốt nhất dựa trên dữ liệu.
Ngày 268: Weights & Biases - So Sánh Với MLflow
Mục tiêu: Biết công cụ SaaS phổ biến khác, có tính năng nâng cao hơn MLflow ở một số điểm.
Lý thuyết: W&B có thêm tính năng: hyperparameter sweep tự động, so sánh trực quan mạnh hơn, tích hợp report chia sẻ; đánh đổi giữa self-hosted (MLflow) vs SaaS (W&B) về chi phí, bảo mật dữ liệu, tiện lợi.
Thực hành: Tích hợp W&B vào cùng training loop, thử tính năng sweep tự động quét vài giá trị learning rate, so sánh trải nghiệm với MLflow.
Ngày 269: Data Versioning
Mục tiêu: Hiểu vấn đề riêng của việc version hoá dữ liệu lớn.
Lý thuyết: Git không phù hợp cho file lớn (dataset hàng chục/hàng trăm GB) - chậm, phình repo; cần công cụ riêng theo dõi version dữ liệu mà không lưu trực tiếp file lớn trong git.
Thực hành: Thử
git addmột file dataset lớn để tự trải nghiệm vấn đề (repo phình to, chậm), rồi tìm hiểu cách DVC giải quyết bằng con trỏ (pointer file) nhỏ.
Ngày 270: DVC - Thực Hành Data Versioning & Pipeline
Mục tiêu: Có kỹ năng thực tế version hoá dataset và pipeline xử lý dữ liệu.
Lý thuyết:
dvc add(theo dõi file lớn, lưu con trỏ vào git),dvc.yamlđịnh nghĩa pipeline các bước xử lý dữ liệu có thể tái tạo (reproducible).Thực hành: Setup DVC cho dataset đã dùng ở các project trước, định nghĩa pipeline (raw data → preprocess → train) bằng
dvc.yaml, thửdvc reprođể tái tạo pipeline.
Ngày 271: Model Registry
Mục tiêu: Hiểu vấn đề quản lý vòng đời model sau khi train xong.
Lý thuyết: Model Registry lưu trữ có version các model đã train, gắn stage (Staging/Production/Archived), cho phép rollback nhanh khi model mới có vấn đề - giải quyết câu hỏi "model nào đang chạy production, phiên bản nào".
Thực hành: Vẽ sơ đồ vòng đời 1 model từ lúc train xong → đăng ký vào registry → staging → production → (nếu có vấn đề) rollback về version trước.
Ngày 272: MLflow Model Registry Thực Hành
Mục tiêu: Thực hành đầy đủ vòng đời registry trên công cụ đã quen thuộc.
Lý thuyết:
mlflow.register_model(), chuyển stage bằng API hoặc UI.Thực hành: Đăng ký model tốt nhất từ Ngày 267 vào MLflow Model Registry, chuyển qua các stage Staging → Production, thử rollback về version cũ hơn.
Ngày 273: Vertex AI Registry & SageMaker Registry - Tổng Quan
Mục tiêu: Biết các lựa chọn managed service của cloud lớn, khi nào nên dùng thay vì self-host MLflow.
Lý thuyết: Vertex AI Model Registry (Google Cloud), SageMaker Model Registry (AWS) - tích hợp sẵn với hạ tầng serving/CI-CD của cloud tương ứng, đánh đổi chi phí và độ khoá nhà cung cấp (vendor lock-in) so với self-hosted.
Thực hành: Đọc tài liệu chính thức của cả 2, lập bảng so sánh với MLflow tự host theo tiêu chí: chi phí, độ phức tạp setup, mức độ tích hợp hệ sinh thái.
Ngày 274: TorchServe - Kiến Trúc & Setup
Mục tiêu: Làm quen công cụ serving chính thức của PyTorch.
Lý thuyết: TorchServe kiến trúc worker process xử lý request, model archive (
.marfile) đóng gói model + code xử lý; hỗ trợ batching request tự động.Thực hành: Cài đặt TorchServe, đóng gói model đơn giản (vd ResNet đã train ở Giai đoạn 4) thành
.marfile theo hướng dẫn chính thức.
Ngày 275: TorchServe - Deploy & Custom Handler
Mục tiêu: Có endpoint serving hoạt động thực tế, hiểu cách tuỳ biến logic tiền/hậu xử lý.
Lý thuyết: Custom Handler cho phép viết logic preprocess input/postprocess output tuỳ ý (vd resize ảnh, format lại JSON response).
Thực hành: Viết custom handler cho model Ngày 274, deploy TorchServe, gửi request test qua REST API, đo latency.
Ngày 276: TensorFlow Serving - Kiến Trúc & Setup
Mục tiêu: Làm quen công cụ serving tương ứng phía TensorFlow.
Lý thuyết: TF Serving dùng format
SavedModel, hỗ trợ versioning tự động (nhiều version model cùng lúc, dễ dàng route sang version mới).Thực hành: Export model TF đã train (Giai đoạn 3/8) sang
SavedModel, cài đặt và chạy TF Serving qua Docker.
Ngày 277: TF Serving - gRPC vs REST
Mục tiêu: Biết chọn giao thức phù hợp cho từng use case.
Lý thuyết: REST đơn giản, dễ debug nhưng chậm hơn; gRPC dùng protobuf nhị phân, nhanh hơn đáng kể, phù hợp cho hệ thống nội bộ cần latency thấp.
Thực hành: Gửi cùng 1 request qua cả REST và gRPC tới TF Serving Ngày 276, benchmark latency của cả 2.
Ngày 278: ONNX - Format Trung Gian Đa Framework
Mục tiêu: Hiểu vai trò ONNX như "ngôn ngữ chung" giữa các framework.
Lý thuyết: ONNX (Open Neural Network Exchange) là định dạng biểu diễn model độc lập framework, cho phép train bằng PyTorch nhưng deploy bằng runtime khác tối ưu hơn (ONNX Runtime, TensorRT).
Thực hành: Đọc cấu trúc file ONNX (graph gồm node tương tự GraphDef đã học Giai đoạn 8), liệt kê các ưu điểm/hạn chế khi convert sang ONNX (một số op tuỳ chỉnh có thể không hỗ trợ).
Ngày 279: Convert PyTorch → ONNX & Chạy Với ONNX Runtime
Mục tiêu: Có kinh nghiệm thực tế convert và deploy model qua ONNX.
Lý thuyết:
torch.onnx.export(), cách xử lý dynamic shape khi export (dynamic_axes).Thực hành: Export model ResNet/LLaMA-mini đã train sang ONNX, chạy inference bằng ONNX Runtime, so sánh output và tốc độ với chạy trực tiếp bằng PyTorch.
Ngày 280: TensorRT - Tổng Quan & Kỹ Thuật Tối Ưu
Mục tiêu: Hiểu công cụ tối ưu inference chuyên sâu nhất cho GPU NVIDIA.
Lý thuyết: TensorRT thực hiện layer fusion (tương tự op fusion đã học ở Inductor/XLA, Giai đoạn 7-8 nhưng chuyên biệt hoá tối đa cho GPU NVIDIA), precision calibration (tự động chọn FP16/INT8 cho từng layer dựa trên dữ liệu calibration) để tối đa hoá throughput.
Thực hành: Đọc tài liệu TensorRT, đối chiếu khái niệm layer fusion với XLA fusion (Giai đoạn 8, Ngày 221) và Inductor fusion (Giai đoạn 7, Ngày 200) đã học trước đó.
Ngày 281: Convert Sang TensorRT & Benchmark
Mục tiêu: Có số liệu thực nghiệm so sánh 3 cấp độ tối ưu inference đã học: PyTorch thuần → ONNX Runtime → TensorRT.
Lý thuyết: Ôn lại quy trình build TensorRT engine từ ONNX model.
Thực hành: Convert model ONNX Ngày 279 sang TensorRT engine, benchmark latency/throughput của cả 3 phương án (PyTorch eager, ONNX Runtime, TensorRT) trên cùng model, cùng hardware.
Ngày 282: LLM Serving - Vì Sao Cần Giải Pháp Riêng
Mục tiêu: Hiểu vì sao TorchServe/TF Serving truyền thống không đủ tốt cho LLM.
Lý thuyết: LLM inference có đặc thù riêng: độ dài output không biết trước (autoregressive), KV Cache (đã học Giai đoạn 6) chiếm bộ nhớ lớn và thay đổi động theo từng request, nhiều request đồng thời có độ dài khác nhau - serving framework truyền thống với static batching không xử lý hiệu quả tình huống này.
Thực hành: Liệt kê lại các đặc điểm riêng biệt của LLM inference so với inference model CV/classification thông thường đã serving ở các ngày trước, chuẩn bị tinh thần cho các giải pháp chuyên biệt sắp học.
Ngày 283: vLLM - PagedAttention
Mục tiêu: Hiểu kỹ thuật đột phá giúp vLLM trở thành chuẩn serving LLM phổ biến nhất.
Lý thuyết: PagedAttention lấy cảm hứng từ virtual memory paging trong hệ điều hành - quản lý KV Cache theo các "block" không liên tục thay vì phải cấp phát 1 vùng nhớ liên tục cố định trước cho mỗi request, giảm mạnh lãng phí bộ nhớ (memory fragmentation) và cho phép chia sẻ KV Cache giữa các request giống nhau (vd cùng prompt hệ thống).
Thực hành: Vẽ sơ đồ so sánh cách cấp phát KV Cache truyền thống (liên tục, cấp phát trước theo max length) vs PagedAttention (theo block, cấp phát động), giải thích vì sao cách sau tiết kiệm bộ nhớ hơn.
Ngày 284: vLLM Thực Hành - Serve Model & Benchmark Throughput
Mục tiêu: Có trải nghiệm serving LLM thực tế bằng công cụ chuẩn công nghiệp.
Lý thuyết: Ôn lại KV Cache (Giai đoạn 6) và PagedAttention (Ngày 283) để hiểu vì sao vLLM đạt throughput cao hơn nhiều so với serving thủ công.
Thực hành: Cài đặt vLLM, serve 1 model pretrained/fine-tuned nhỏ (từ Giai đoạn 6), benchmark throughput (request/giây, token/giây) so với serving thủ công bằng TorchServe.
(Còn tiếp: Ngày 285-304 - Continuous Batching, TGI, SGLang, TensorRT-LLM, Eval Harness, Kubernetes, Kubeflow, CI/CD, Observability, Project cuối)
Ngày 285: Continuous Batching
Mục tiêu: Hiểu kỹ thuật thứ 2 (bên cạnh PagedAttention) giúp vLLM/TGI đạt throughput cao.
Lý thuyết: Static batching (chờ đủ 1 batch request giống độ dài rồi mới chạy, phải chờ request dài nhất xong mới nhận batch mới) vs Continuous batching (mỗi khi 1 request trong batch hoàn thành, ngay lập tức "chèn" request mới vào vị trí trống mà không cần chờ cả batch xong) - tăng đáng kể GPU utilization.
Thực hành: Vẽ sơ đồ timeline minh hoạ GPU utilization của static batching (có nhiều khoảng idle chờ) vs continuous batching (GPU luôn bận).
Ngày 286: TGI - Text Generation Inference
Mục tiêu: Biết giải pháp serving LLM khác từ Hugging Face, so sánh với vLLM.
Lý thuyết: TGI cũng dùng continuous batching và các tối ưu tương tự, tích hợp chặt với hệ sinh thái Hugging Face (dễ deploy model từ Hub); so sánh sơ bộ hiệu năng và use case phù hợp giữa TGI và vLLM.
Thực hành: Cài đặt TGI, serve cùng model đã dùng ở Ngày 284, so sánh throughput và độ dễ sử dụng với vLLM.
Ngày 287: SGLang - RadixAttention & Structured Generation
Mục tiêu: Biết giải pháp serving thế hệ mới, tối ưu cho các use case phức tạp hơn (agent, structured output).
Lý thuyết: RadixAttention mở rộng ý tưởng chia sẻ KV Cache (đã gợi mở ở PagedAttention, Ngày 283) bằng cấu trúc cây radix để tự động phát hiện và tái sử dụng KV Cache giữa nhiều request có phần prefix chung; hỗ trợ tốt cho structured generation (ép output theo schema/JSON).
Thực hành: Đọc tài liệu SGLang, thử ví dụ structured generation (ép model sinh JSON đúng schema), so sánh với cách ép format thủ công bằng prompt engineering thông thường.
Ngày 288: TensorRT-LLM - Engine Building Cho LLM
Mục tiêu: Biết giải pháp tối ưu sâu nhất cho GPU NVIDIA, dành cho khi cần tối đa hiệu năng.
Lý thuyết: TensorRT-LLM kết hợp các tối ưu kernel-level (tương tự TensorRT thường đã học Ngày 280-281 nhưng chuyên biệt cho kiến trúc Transformer/LLM) như fused attention kernel, in-flight batching, quantization tích hợp sẵn (INT8/INT4, đã học Giai đoạn 6).
Thực hành: Đọc quy trình build TensorRT-LLM engine cho 1 model LLaMA-style, lập bảng so sánh 4 giải pháp serving đã học (vLLM/TGI/SGLang/TensorRT-LLM) theo tiêu chí: độ dễ setup, throughput, độ linh hoạt, mức độ tối ưu phần cứng.
Ngày 289: Evaluation - lm-eval-harness & Benchmark Chuẩn
Mục tiêu: Biết cách đánh giá LLM một cách có hệ thống, không chỉ nhìn "cảm tính".
Lý thuyết:
lm-evaluation-harness- framework chuẩn hoá chạy nhiều benchmark (MMLU, HellaSwag, GSM8K...) trên bất kỳ model nào theo cùng 1 giao thức, giúp so sánh công bằng giữa các model.Thực hành: Cài đặt
lm-eval-harness, đọc qua danh sách benchmark có sẵn, chọn 1-2 benchmark phù hợp với model nhỏ đã train.
Ngày 290: Chạy Eval Harness & Diễn Giải Kết Quả
Mục tiêu: Có kinh nghiệm thực tế đánh giá model đã fine-tune ở Giai đoạn 6.
Lý thuyết: Ôn lại cách đọc kết quả benchmark (accuracy, few-shot vs zero-shot setting).
Thực hành: Chạy
lm-eval-harnesstrên model SFT/LoRA đã fine-tune (Giai đoạn 6, Ngày 168/174), so sánh kết quả trước/sau fine-tune trên benchmark đã chọn.
Ngày 291: Đánh Giá Hallucination & Chất Lượng Output
Mục tiêu: Biết các phương pháp đánh giá vượt ra ngoài benchmark trắc nghiệm chuẩn.
Lý thuyết: Hallucination - model sinh thông tin sai nhưng tự tin; các hướng đánh giá: dùng model khác làm giám khảo (LLM-as-judge), so khớp với nguồn tham chiếu (factuality check), đánh giá con người (human eval) vẫn là gold standard.
Thực hành: Thiết kế 1 bộ câu hỏi test nhỏ để kiểm tra hallucination của model đã fine-tune, thử phương pháp LLM-as-judge (dùng 1 model khác chấm điểm câu trả lời) và so sánh với đánh giá thủ công.
Ngày 292: Kubernetes Fundamentals - Ôn Tập Nhanh
Mục tiêu: Đảm bảo nền K8s đủ vững trước khi học các phần nâng cao dành riêng cho ML workload.
Lý thuyết: Pod (đơn vị chạy nhỏ nhất), Deployment (quản lý vòng đời nhiều Pod giống nhau), Service (expose Pod ra network) - ôn nhanh nếu đã biết, học kỹ nếu chưa.
Thực hành: Deploy 1 ứng dụng đơn giản (vd container serving model Ngày 275) lên K8s cluster (local bằng
minikube/kindnếu không có cloud), verify truy cập được qua Service.
Ngày 293: GPU Node Scheduling Trong K8s
Mục tiêu: Biết cách K8s quản lý tài nguyên GPU - khác biệt so với CPU/RAM thông thường.
Lý thuyết: NVIDIA Device Plugin cho phép K8s nhận diện GPU như 1 loại resource có thể request (
nvidia.com/gpu: 1); GPU không thể chia nhỏ như CPU (mỗi Pod thường chiếm nguyên 1 GPU trừ khi dùng MIG - Multi-Instance GPU).Thực hành: Viết Deployment YAML có request GPU resource, verify Pod được schedule đúng lên node có GPU.
Ngày 294: HPA - Horizontal Pod Autoscaler Cho ML Workload
Mục tiêu: Hiểu cách tự động scale số lượng Pod serving theo tải.
Lý thuyết: HPA theo dõi metric (CPU/memory hoặc custom metric như request/giây, GPU utilization) và tự động tăng/giảm số Pod; với inference workload, custom metric (latency, queue length) thường hữu ích hơn CPU utilization thuần.
Thực hành: Cấu hình HPA cho Deployment serving model Ngày 292, mô phỏng tải tăng đột biến (load test), quan sát HPA tự động scale.
Ngày 295: KEDA - Event-Driven Autoscaling & Scale-to-Zero
Mục tiêu: Biết giải pháp autoscaling nâng cao hơn HPA, đặc biệt hữu ích để tiết kiệm chi phí GPU.
Lý thuyết: KEDA cho phép scale dựa trên nhiều nguồn event khác nhau (message queue length, thời gian biểu...) và hỗ trợ scale-to-zero (giảm về 0 Pod khi không có request, tiết kiệm chi phí GPU đắt đỏ) - điều HPA chuẩn không hỗ trợ tốt.
Thực hành: Cấu hình KEDA cho service inference dựa trên độ dài queue request, thử để service tự scale về 0 khi idle rồi tự "wake up" khi có request mới, đo thời gian cold-start.
Ngày 296: Xây Dựng Inference Service Hoàn Chỉnh Trên K8s
Mục tiêu: Tổng hợp toàn bộ kiến thức K8s thành 1 deployment production-grade hoàn chỉnh.
Lý thuyết: Ôn lại toàn bộ: Deployment (GPU resource request) + Service + HPA/KEDA + health check (
livenessProbe/readinessProbe) + resource limit.Thực hành: Viết bộ YAML đầy đủ (Deployment, Service, HPA) deploy model serving bằng vLLM (Ngày 284) lên K8s, có health check và resource limit hợp lý.
Ngày 297: Kubeflow - Tổng Quan Pipelines
Mục tiêu: Biết công cụ orchestration ML workflow phổ biến trên K8s.
Lý thuyết: Kubeflow Pipelines cho phép định nghĩa workflow ML (data prep → train → eval → deploy) dưới dạng DAG (Directed Acyclic Graph) các component có thể tái sử dụng, chạy trên K8s.
Thực hành: Đọc tài liệu Kubeflow Pipelines, vẽ sơ đồ DAG cho pipeline huấn luyện đã làm trong lộ trình (từ Dataset → Train → Eval → Register model).
Ngày 298: Xây Kubeflow Pipeline Đơn Giản
Mục tiêu: Có kinh nghiệm thực tế build 1 pipeline chạy được.
Lý thuyết: Ôn lại cú pháp định nghĩa component và pipeline bằng Kubeflow SDK (Python).
Thực hành: Viết 1 pipeline Kubeflow đơn giản gồm 2-3 bước (vd preprocess data → train → eval) dựa trên project đã có, chạy thử trên Kubeflow (hoặc local nếu không có cluster đầy đủ).
Ngày 299: CI/CD Cho ML - Testing & Validation Gates
Mục tiêu: Hiểu CI/CD cho ML khác CI/CD phần mềm thông thường thế nào.
Lý thuyết: Ngoài unit test code thông thường, ML cần thêm: data validation test (schema, phân phối dữ liệu không lệch bất thường), model validation gate (model mới phải vượt qua ngưỡng metric tối thiểu mới được promote lên production) - tránh regression khi deploy model mới.
Thực hành: Viết pipeline CI (GitHub Actions hoặc tương đương) chạy test cơ bản (unit test code, data schema check) và 1 validation gate (model mới phải đạt accuracy tối thiểu so với model hiện tại) trước khi cho phép merge/deploy.
Ngày 300: Observability - Structured Logging Cho ML Service
Mục tiêu: Xây thói quen logging đúng chuẩn production, dễ truy vấn khi có sự cố.
Lý thuyết: Structured logging (log dưới dạng JSON có field rõ ràng thay vì text tự do) giúp dễ dàng filter/aggregate; những gì cần log cho ML service (request_id, latency, model_version, input shape, confidence score).
Thực hành: Thêm structured logging vào inference service (Ngày 296), log đầy đủ thông tin cần thiết cho mỗi request, thử truy vấn log để trả lời câu hỏi "request nào chậm nhất trong giờ qua".
Ngày 301: Observability - Tracing Xuyên Suốt Pipeline
Mục tiêu: Hiểu cách theo dõi 1 request đi qua nhiều service/bước xử lý (đặc biệt quan trọng nếu có RAG/multi-step pipeline).
Lý thuyết: Distributed tracing (vd OpenTelemetry) gắn 1
trace_idxuyên suốt để theo dõi latency của từng bước con trong 1 request tổng thể, giúp xác định chính xác bước nào chậm khi hệ thống có nhiều thành phần.Thực hành: Tích hợp tracing cơ bản vào inference service, giả lập pipeline có 2-3 bước (preprocess → inference → postprocess), visualize trace để thấy rõ latency breakdown từng bước.
Ngày 302: Model Drift & Data Drift Detection
Mục tiêu: Hiểu vấn đề model xuống cấp âm thầm theo thời gian trong production.
Lý thuyết: Data drift (phân phối dữ liệu input thực tế thay đổi so với lúc train) và model/concept drift (mối quan hệ input-output thay đổi theo thời gian, vd hành vi người dùng đổi); các phương pháp phát hiện đơn giản (theo dõi phân phối feature theo thời gian, so sánh với baseline lúc train).
Thực hành: Viết script đơn giản so sánh phân phối input thực tế (giả lập) với phân phối dữ liệu training, cảnh báo khi lệch vượt ngưỡng.
Ngày 303: Project - Deploy Fine-tuned LLM Với vLLM Trên K8s + Monitoring
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 10 thành 1 hệ thống production hoàn chỉnh.
Lý thuyết: Ôn lại toàn bộ pipeline: model registry → serving (vLLM) → K8s deployment (HPA/KEDA) → observability (logging/tracing) → drift detection.
Thực hành: Deploy model LoRA fine-tune (Giai đoạn 6) bằng vLLM lên K8s, có đầy đủ HPA, structured logging, tracing cơ bản, và 1 dashboard đơn giản hiển thị metric (latency, throughput, error rate).
Ngày 304: Checkpoint & Review Giai đoạn 10
Mục tiêu: Củng cố toàn bộ kiến thức MLOps/Production, chuẩn bị sang phần Research Engineer.
Lý thuyết: Tổng hợp lại: Experiment Tracking → Data/Model Versioning → Serving (truyền thống & LLM chuyên biệt) → Inference Optimization (ONNX/TensorRT) → Kubernetes → CI/CD → Observability.
Thực hành: Tự kiểm tra: giải thích vì sao vLLM nhanh hơn TorchServe cho LLM (PagedAttention + Continuous Batching) cho người không biết gì; vẽ lại kiến trúc hệ thống production hoàn chỉnh (từ Ngày 303) từ trí nhớ.
Checkpoint cuối Giai đoạn 10
Hệ thống production ở Ngày 303 có đầy đủ: serving, autoscaling, logging, tracing, drift detection không?
Có thể tự tin trả lời phỏng vấn về sự khác biệt PagedAttention vs KV Cache truyền thống không?
Đã có tài liệu/kinh nghiệm đủ để tự thiết kế 1 ML platform từ đầu cho công ty thực tế chưa?
Nếu ổn, tiếp tục sang Giai đoạn 11 - Research (đọc & tái hiện paper).
Giai Đoạn 11 - Research (Ngày 305 - 324)
Mục tiêu giai đoạn: Rèn kỹ năng đọc paper một cách có hệ thống và đối chiếu với những gì đã tự tay implement suốt 304 ngày trước - biến kiến thức thực hành thành khả năng đọc hiểu literature một cách độc lập, kỹ năng sẽ cần dùng liên tục trong suốt sự nghiệp.
Ngày 305: Phương Pháp Đọc Paper Hiệu Quả
Mục tiêu: Có quy trình đọc paper có hệ thống thay vì đọc lan man.
Lý thuyết: Phương pháp "3-pass" - pass 1 (đọc title/abstract/kết luận, nắm ý tưởng tổng quát trong 5-10 phút), pass 2 (đọc kỹ hình vẽ/bảng số liệu, hiểu phương pháp ở mức trung bình), pass 3 (đọc chi tiết toàn bộ, có thể tái hiện lại kết quả).
Thực hành: Chọn 1 paper ngắn chưa đọc, áp dụng thử cả 3 pass, ghi lại thời gian và mức độ hiểu đạt được sau mỗi pass.
Ngày 306: Đọc Lại Formal - ResNet Paper
Mục tiêu: Đối chiếu hiểu biết thực hành (đã tự cài ở Giai đoạn 4) với văn bản gốc chính thức.
Lý thuyết: Đọc paper gốc "Deep Residual Learning for Image Recognition" bằng phương pháp 3-pass.
Thực hành: Viết tóm tắt (bằng lời riêng, không trích dẫn nguyên văn) so sánh những gì paper trình bày với những gì đã tự implement ở Giai đoạn 4 (Ngày 104-105) - ghi chú những chi tiết paper có mà lúc tự cài đã bỏ qua.
Ngày 307: Đọc Lại Formal - "Attention Is All You Need"
Mục tiêu: Đọc paper nền tảng nhất của toàn bộ Giai đoạn 6 một cách trọn vẹn.
Lý thuyết: Đọc kỹ phần kiến trúc, phần thí nghiệm và ablation study (paper thử bỏ từng thành phần để chứng minh mỗi phần đều cần thiết).
Thực hành: Đối chiếu bảng ablation trong paper với hiểu biết đã có từ việc tự cài Transformer (Giai đoạn 6, Ngày 130-143), viết nhận xét về những thiết kế "tưởng nhỏ nhưng quan trọng" mà paper chỉ ra.
Ngày 308: Đọc Lại Formal - BERT Paper
Mục tiêu: Hiểu sâu hơn phần thí nghiệm mà lúc tự cài (Giai đoạn 6, Ngày 147-148) chưa có điều kiện làm ở quy mô đầy đủ.
Lý thuyết: Đọc phần fine-tuning cho các downstream task khác nhau (GLUE benchmark), phần ablation về MLM vs NSP.
Thực hành: Tóm tắt bằng lời riêng cách BERT được fine-tune cho từng loại task (classification, QA, NER) chỉ bằng cách thay đổi output head.
Ngày 309: Đọc - GPT-2 Paper
Mục tiêu: Hiểu bước chuyển quan trọng: từ "pretrain rồi fine-tune" sang khả năng zero-shot.
Lý thuyết: "Language Models are Unsupervised Multitask Learners" - luận điểm chính: 1 language model đủ lớn, train trên đủ dữ liệu đa dạng, có thể thực hiện nhiều task khác nhau mà không cần fine-tune riêng (zero-shot), chỉ cần đúng cách "hỏi" (prompt).
Thực hành: Thử nghiệm zero-shot với GPT-mini đã train (Giai đoạn 6, Ngày 150) trên vài task đơn giản, so sánh khả năng thực tế với luận điểm paper đưa ra (model nhỏ tự train sẽ yếu hơn nhiều - quan sát và giải thích tại sao qua góc nhìn scale).
Ngày 310: Đọc - GPT-3 Paper & In-Context Learning
Mục tiêu: Hiểu hiện tượng in-context learning - nền tảng của prompt engineering hiện đại.
Lý thuyết: "Language Models are Few-Shot Learners" - model đủ lớn có thể "học" từ vài ví dụ đưa trực tiếp trong prompt (few-shot) mà không cần cập nhật trọng số; mối liên hệ với scaling law đã học sơ lược ở Giai đoạn 6 (Ngày 165).
Thực hành: Thử few-shot prompting với model instruction-tuned đã có (Giai đoạn 6, Ngày 168), so sánh chất lượng zero-shot vs few-shot trên cùng 1 task.
Ngày 311: Đọc Sâu - LoRA Paper
Mục tiêu: Hiểu dẫn xuất toán học đầy đủ đằng sau kỹ thuật đã tự cài ở Giai đoạn 6 (Ngày 174).
Lý thuyết: Đọc kỹ phần giả thuyết "intrinsic rank" (trọng số update khi fine-tune thực chất có rank thấp), phần thí nghiệm so sánh LoRA với các phương pháp PEFT khác trên nhiều model size.
Thực hành: Đối chiếu công thức toán trong paper với code LoRA đã tự viết, verify từng dòng code tương ứng chính xác với công thức nào trong paper.
Ngày 312: Đọc Sâu - RoPE Paper
Mục tiêu: Hiểu dẫn xuất toán học đầy đủ của kỹ thuật đã tự cài ở Giai đoạn 6 (Ngày 136).
Lý thuyết: Đọc kỹ phần chứng minh toán học vì sao phép xoay (rotation) trong không gian phức tạo ra tính chất vị trí tương đối thông qua dot product.
Thực hành: Tự dẫn lại (trên giấy) chứng minh chính trong paper, đối chiếu với code RoPE đã tự viết để verify hiểu đúng.
Ngày 313: Đọc - LLaMA Paper (Series)
Mục tiêu: Hiểu quyết định thiết kế và insight training thực tế từ 1 trong những họ model có ảnh hưởng nhất.
Lý thuyết: Đọc phần kiến trúc (đối chiếu với những gì đã tự cài Giai đoạn 6, Ngày 160-161), phần dữ liệu pretraining, và các bài học thực tế về training instability (nếu paper đề cập).
Thực hành: Tóm tắt các quyết định kiến trúc chính của LLaMA và lý do đằng sau mỗi quyết định (bằng lời riêng), đối chiếu với bảng so sánh kiến trúc đã lập ở Giai đoạn 6 (Ngày 164).
Ngày 314: Đọc - DeepSeek-V3 Paper
Mục tiêu: Hiểu chi tiết kỹ thuật MoE và MLA đã học sơ lược ở Giai đoạn 6 (Ngày 163).
Lý thuyết: Đọc kỹ phần chi tiết routing strategy của MoE (cách cân bằng tải giữa các expert - load balancing loss), phần chi tiết Multi-Head Latent Attention và cách nó giảm KV cache.
Thực hành: Vẽ lại sơ đồ MoE routing chi tiết hơn dựa trên paper (so với sơ đồ đơn giản đã vẽ ở Ngày 163), ghi chú thêm về load balancing.
Ngày 315: Tái Hiện Một Phần Paper Chưa Implement (Phần 1)
Mục tiêu: Thực hành kỹ năng quan trọng nhất của research engineer: biến paper thành code chạy được từ đầu.
Lý thuyết: Chọn 1 kỹ thuật trong số các paper đã đọc mà chưa từng tự tay implement đầy đủ (vd load balancing loss của MoE, hoặc phần ablation cụ thể nào đó của 1 paper).
Thực hành: Bắt đầu implement phần đã chọn, chỉ dựa vào paper gốc (không xem code tham khảo có sẵn) để rèn khả năng đọc-hiểu-viết độc lập.
Ngày 316: Tái Hiện Một Phần Paper Chưa Implement (Phần 2)
Mục tiêu: Hoàn thiện và verify kết quả tái hiện.
Lý thuyết: Ôn lại phần đã đọc Ngày 315, đối chiếu thêm nếu có phần chưa rõ.
Thực hành: Hoàn thiện implementation, verify kết quả hợp lý (so với mô tả định tính trong paper nếu không có đủ tài nguyên tái hiện số liệu chính xác), viết ghi chú về những khó khăn gặp phải khi chuyển từ paper sang code.
Ngày 317: Đọc Một Paper Mới/Gần Đây
Mục tiêu: Rèn kỹ năng đọc paper trên lãnh thổ hoàn toàn mới, không có sẵn kiến thức nền như các paper kinh điển đã học.
Lý thuyết: Tìm kiếm 1 paper LLM/DL đáng chú ý gần đây (dùng công cụ tìm kiếm để cập nhật, vì lĩnh vực này thay đổi liên tục sau thời điểm lộ trình này được viết), áp dụng phương pháp 3-pass Ngày 305.
Thực hành: Viết tóm tắt paper mới này theo đúng format đã dùng cho các paper trước, tự đánh giá mức độ hiểu đạt được so với các paper kinh điển đã quen thuộc.
Ngày 318: Viết Bài Tổng Hợp Về Một Paper
Mục tiêu: Rèn kỹ năng truyền đạt - khả năng giải thích paper phức tạp cho người khác, kỹ năng quan trọng của senior engineer.
Lý thuyết: Cấu trúc 1 bài blog kỹ thuật tốt: vấn đề paper giải quyết → ý tưởng cốt lõi (giải thích trực giác trước, toán sau) → kết quả chính → hạn chế.
Thực hành: Viết 1 bài blog/note kỹ thuật hoàn chỉnh về 1 paper tâm đắc nhất trong số đã đọc (vd RoPE hoặc Flash Attention), nhắm tới đối tượng độc giả là người mới học.
Ngày 319: Đọc Sâu - Chinchilla Scaling Law Paper
Mục tiêu: Hiểu chi tiết toán học đằng sau khái niệm đã học sơ lược ở Giai đoạn 6 (Ngày 165).
Lý thuyết: Đọc phương pháp thí nghiệm (train nhiều model ở nhiều scale khác nhau để fit công thức scaling law), kết luận chính về tỉ lệ tối ưu giữa số tham số và số token training.
Thực hành: Dùng công thức scaling law trong paper, tính thử: với 1 compute budget cho trước, model size và data size tối ưu nên là bao nhiêu.
Ngày 320: Đọc Sâu - InstructGPT/RLHF Paper
Mục tiêu: Hiểu chi tiết đầy đủ pipeline đã học sơ lược ở Giai đoạn 6 (Ngày 169-170).
Lý thuyết: Đọc kỹ phần thu thập dữ liệu human preference, phần thiết kế reward model, và kết quả cho thấy model nhỏ hơn nhưng đã RLHF có thể được người dùng ưa thích hơn model lớn hơn nhưng chỉ pretrain.
Thực hành: Tóm tắt lại toàn bộ pipeline 3 bước (SFT → Reward Model → PPO) với chi tiết đầy đủ hơn so với ghi chú sơ lược ở Giai đoạn 6.
Ngày 321: Đọc Sâu - Paper Hệ Thống (Megatron-LM hoặc FlashAttention)
Mục tiêu: Đối chiếu hiểu biết thực hành hệ thống (Giai đoạn 7, 9) với paper gốc.
Lý thuyết: Đọc kỹ phần thí nghiệm benchmark hiệu năng, các con số cụ thể về speedup mà paper báo cáo.
Thực hành: So sánh số liệu benchmark tự đo được (Giai đoạn 6 Ngày 156 cho Flash Attention, hoặc Giai đoạn 9 cho Tensor Parallel nếu chọn Megatron-LM) với số liệu paper công bố, giải thích chênh lệch nếu có (khác phần cứng, khác quy mô).
Ngày 322: Đọc Sâu - ZeRO Paper
Mục tiêu: Hiểu chi tiết đầy đủ hơn kỹ thuật đã học ở Giai đoạn 9 (Ngày 245).
Lý thuyết: Đọc kỹ phần phân tích bộ nhớ (memory breakdown) cho từng stage ZeRO, phần thí nghiệm scale tới model rất lớn.
Thực hành: Tính lại bảng bộ nhớ đã lập ở Giai đoạn 9 (Ngày 245) với công thức chính xác từ paper, so sánh với ước tính trực giác đã làm trước đó.
Ngày 323: Project - Biên Soạn Tài Liệu Ghi Chú Paper Cá Nhân
Mục tiêu: Có 1 tài liệu tham chiếu tổng hợp giá trị lâu dài từ toàn bộ Giai đoạn 11.
Lý thuyết: Ôn lại toàn bộ các paper đã đọc.
Thực hành: Tổng hợp toàn bộ ghi chú/tóm tắt của 9+ paper đã đọc trong giai đoạn này thành 1 tài liệu có cấu trúc (theo chủ đề: Kiến trúc/Training/Hệ thống), có thể dùng lại khi cần ôn nhanh hoặc chia sẻ với đồng nghiệp.
Ngày 324: Checkpoint & Review Giai đoạn 11
Mục tiêu: Củng cố kỹ năng đọc paper độc lập trước khi bước vào Capstone.
Lý thuyết: Tổng hợp lại: phương pháp 3-pass, kỹ năng đối chiếu paper với implementation thực tế, kỹ năng viết tóm tắt truyền đạt lại cho người khác.
Thực hành: Tự kiểm tra bằng cách chọn ngẫu nhiên 1 paper mới hoàn toàn chưa đọc, áp dụng pass 1+2 trong 30 phút, đánh giá xem có đủ tự tin giải thích ý tưởng chính cho đồng nghiệp không.
Checkpoint cuối Giai đoạn 11
Có tài liệu ghi chú paper cá nhân đủ chi tiết để dùng tham chiếu lâu dài không?
Có thể đọc 1 paper mới hoàn toàn và nắm được ý chính trong vòng 15-20 phút không?
Đã tái hiện được ít nhất 1 phần kỹ thuật hoàn toàn mới chỉ từ đọc paper (không xem code tham khảo) chưa?
Lưu ý quan trọng: Giai đoạn này về bản chất là liên tục - trong thực tế công việc, nên duy trì thói quen đọc 1 paper/tuần ngay cả sau khi hoàn thành lộ trình. Tiếp tục sang phần Capstone - 5 dự án tổng hợp cuối cùng.
Dự Án Capstone Cuối Cùng (Ngày 325 - 350)
Mục tiêu giai đoạn: Tổng hợp toàn bộ 324 ngày học thành 5 dự án thực chiến hoàn chỉnh, đủ chất lượng để đưa vào portfolio hoặc trình bày trong phỏng vấn senior-level.
Project 1 - Autograd Engine & Tensor Library Tối Giản (Ngày 325 - 328)
Ngày 325: Thiết Kế Kiến Trúc Tensor Library
Mục tiêu: Có bản thiết kế rõ ràng trước khi code, đúng tinh thần kỹ sư chuyên nghiệp.
Lý thuyết: Ôn lại toàn bộ: TensorImpl/Storage (Giai đoạn 7), mini-autograd engine (Giai đoạn 2), N-dimensional array với stride (Giai đoạn 0/2).
Thực hành: Viết design doc (API tương tự PyTorch:
Tensor,.backward(),nn.Module-like layer) cho thư viện sẽ xây, xác định rõ scope (hỗ trợ CPU only, N chiều, các op cơ bản).
Ngày 326: Implement Tensor Class Với Storage & Autograd N-chiều
Mục tiêu: Mở rộng mini-engine (vốn chỉ làm việc với số vô hướng ở Giai đoạn 2) thành hỗ trợ đầy đủ N-dimensional tensor.
Lý thuyết: Ôn lại cách NumPy quản lý stride cho N chiều (Giai đoạn 0), kết hợp với cơ chế autograd (Value class, Giai đoạn 2).
Thực hành: Implement class
Tensordùng NumPy array làm Storage nội bộ, hỗ trợrequires_grad,.backward()hoạt động đúng cho các phép toán N-chiều (matmul, broadcasting).
Ngày 327: Implement Layer System
Mục tiêu: Có hệ thống
nn.Module-like hoàn chỉnh trên nền Tensor Library tự viết.Lý thuyết: Ôn lại thiết kế
nn.Module(Giai đoạn 2, Ngày 53-54).Thực hành: Implement
Modulebase class,Linear,ReLU,Sequential,SGD/Adamoptimizer - toàn bộ chạy trên Tensor tự viết Ngày 326, không phụ thuộc PyTorch.
Ngày 328: Train MNIST End-to-End & So Sánh Với PyTorch
Mục tiêu: Chứng minh framework tự viết hoạt động thực tế, khép lại Project 1.
Lý thuyết: Ôn lại toàn bộ training loop chuẩn.
Thực hành: Train MLP trên MNIST hoàn toàn bằng framework tự viết, so sánh accuracy/tốc độ với cùng kiến trúc chạy trên PyTorch thật, viết báo cáo ngắn về những khó khăn/insight thu được khi tự xây 1 framework từ số 0.
Project 2 - Transformer Từ Paper, Không Dùng Hugging Face (Ngày 329 - 332)
Ngày 329: Đọc Kỹ & Lên Kế Hoạch Implementation
Mục tiêu: Đảm bảo implementation bám sát đúng paper gốc, không dựa vào ký ức mơ hồ.
Lý thuyết: Đọc lại "Attention Is All You Need" (đã đọc formal ở Giai đoạn 11, Ngày 307) với mục tiêu cụ thể: liệt kê chính xác từng siêu tham số (số layer, d_model, số head, dropout rate) paper dùng.
Thực hành: Viết checklist implementation đầy đủ dựa trên paper, không xem lại code Transformer đã viết ở Giai đoạn 6 để tự thử thách khả năng implement độc lập.
Ngày 330: Implement Full Transformer Từ Đầu
Mục tiêu: Có bản Transformer hoàn chỉnh, sạch, đúng chuẩn paper.
Lý thuyết: Ôn lại toàn bộ kiến trúc encoder-decoder đã học Giai đoạn 6.
Thực hành: Viết lại toàn bộ Transformer từ đầu (không copy code cũ), theo đúng checklist Ngày 329, chỉ dùng PyTorch thuần (không
transformerslibrary của Hugging Face).
Ngày 331: Train Trên Bài Toán Dịch Máy Nhỏ
Mục tiêu: Kiểm chứng implementation trên bài toán thực tế gần với paper gốc nhất (paper gốc thử nghiệm trên dịch máy).
Lý thuyết: Ôn lại tokenization (BPE, Giai đoạn 6, Ngày 144-145) áp dụng cho cặp ngôn ngữ.
Thực hành: Chuẩn bị 1 dataset dịch máy nhỏ (vd cặp câu Anh-Việt quy mô nhỏ), tokenize bằng BPE tự viết, train Transformer Ngày 330 trên dataset này.
Ngày 332: Đánh Giá Bằng BLEU Score
Mục tiêu: Đánh giá chất lượng model bằng metric chuẩn của bài toán dịch máy, khép lại Project 2.
Lý thuyết: BLEU score - metric đo độ trùng khớp n-gram giữa output model và bản dịch tham chiếu.
Thực hành: Cài đặt hoặc dùng thư viện tính BLEU score cho output của model đã train, so sánh với baseline đơn giản (vd dịch từng từ), viết báo cáo tổng kết Project 2.
Project 3 - Huấn Luyện LLM Nhỏ 100M-500M Tham Số (Ngày 333 - 338)
Ngày 333: Chuẩn Bị Dữ Liệu Pretraining
Mục tiêu: Có data pipeline sẵn sàng cho pretraining quy mô lớn hơn mọi project trước đó trong lộ trình.
Lý thuyết: Ôn lại xử lý dataset lớn (Giai đoạn 2, Ngày 64), data quality filtering (Giai đoạn 6, Ngày 165).
Thực hành: Thu thập/chuẩn bị 1 corpus text đủ lớn (tuỳ tài nguyên, có thể dùng tập con của các corpus mở có sẵn), xây pipeline tokenize + sharding hiệu quả.
Ngày 334: Thiết Kế Kiến Trúc Model
Mục tiêu: Chọn cấu hình kiến trúc hợp lý cho quy mô 100M-500M tham số.
Lý thuyết: Ôn lại LLaMA-style block (Giai đoạn 6, Ngày 160-161), cân nhắc số layer/hidden dim/số head phù hợp với compute budget hiện có (liên hệ Chinchilla scaling law, Giai đoạn 11, Ngày 319).
Thực hành: Tính toán và chọn cấu hình kiến trúc cụ thể (số layer, d_model, số head, vocab size) để đạt đúng khoảng 100M-500M tham số, verify bằng cách đếm tham số thực tế sau khi khởi tạo model.
Ngày 335: Setup Training Infrastructure
Mục tiêu: Chuẩn bị hạ tầng training đủ mạnh cho quy mô này.
Lý thuyết: Ôn lại FSDP (Giai đoạn 9, Ngày 243-244), mixed precision BF16 (Ngày 254), gradient checkpointing (Ngày 256).
Thực hành: Setup training script đầy đủ FSDP + BF16 + gradient checkpointing + logging (MLflow/W&B, Giai đoạn 10), test chạy thử vài step để verify không lỗi trước khi train dài hạn.
Ngày 336: Chạy Pretraining & Theo Dõi
Mục tiêu: Thực chiến quá trình pretraining, xử lý các vấn đề phát sinh thực tế.
Lý thuyết: Ôn lại debug loss spike/NaN (Giai đoạn 9, Ngày 257-258).
Thực hành: Chạy pretraining thực tế (thời gian tuỳ tài nguyên GPU sẵn có), theo dõi loss curve liên tục qua MLflow/W&B, xử lý ngay nếu có instability xảy ra.
Ngày 337: SFT Fine-tune Model Đã Pretrain
Mục tiêu: Biến base model thành model biết làm theo chỉ dẫn.
Lý thuyết: Ôn lại SFT (Giai đoạn 6, Ngày 167-168).
Thực hành: Chuẩn bị dataset instruction phù hợp quy mô model, fine-tune bằng SFT (có thể dùng LoRA nếu tài nguyên hạn chế, Ngày 174).
Ngày 338: Evaluate & Viết Báo Cáo
Mục tiêu: Đánh giá khách quan chất lượng model, khép lại Project 3.
Lý thuyết: Ôn lại
lm-eval-harness(Giai đoạn 10, Ngày 289-290).Thực hành: Chạy eval harness trên model đã pretrain+SFT, so sánh với các model mở cùng quy mô tham số nếu có baseline công khai, viết báo cáo kỹ thuật đầy đủ (data, kiến trúc, compute dùng, kết quả eval).
Project 4 - Distributed Training Trên Nhiều GPU (Ngày 339 - 343)
Ngày 339: Thiết Kế Chiến Lược Song Song Hoá
Mục tiêu: Áp dụng tư duy hệ thống đã học ở Giai đoạn 9 vào 1 tình huống cụ thể.
Lý thuyết: Ôn lại Data/Tensor/Pipeline/Sequence Parallelism và 3D Parallelism (Giai đoạn 9, Ngày 240-252).
Thực hành: Dựa trên số GPU thực tế có sẵn (hoặc giả định 1 cluster cụ thể), thiết kế chiến lược song song hoá phù hợp cho model Project 3 (hoặc 1 model lớn hơn), viết rõ lý do lựa chọn.
Ngày 340: Setup Multi-GPU Cluster
Mục tiêu: Có hạ tầng thực tế để chạy distributed training.
Lý thuyết: Ôn lại cách khởi tạo process group,
torchrun/torch.distributed.launch(Giai đoạn 9, Ngày 241), hoặc cấu hình multi-node nếu có điều kiện.Thực hành: Setup môi trường (multi-GPU 1 máy, hoặc thuê cloud instance nhiều GPU nếu cần), verify NCCL communication hoạt động đúng giữa các GPU/node.
Ngày 341: Chạy Distributed Training & Benchmark Scaling Efficiency
Mục tiêu: Có số liệu thực nghiệm về hiệu quả scale khi tăng số GPU.
Lý thuyết: Scaling efficiency - throughput thực tế khi tăng N GPU so với lý tưởng (N lần throughput 1 GPU); các yếu tố làm giảm hiệu quả (communication overhead).
Thực hành: Chạy cùng 1 training job với 1, 2, 4... GPU (tuỳ tài nguyên), đo throughput mỗi cấu hình, tính scaling efficiency, vẽ biểu đồ.
Ngày 342: Profile & Tối Ưu Bottleneck
Mục tiêu: Đưa hiệu năng distributed training lên gần tối ưu.
Lý thuyết: Ôn lại PyTorch Profiler cho multi-GPU (Giai đoạn 9, Ngày 259).
Thực hành: Profile training job, xác định bottleneck (communication? data loading? compute?), áp dụng ít nhất 1-2 tối ưu cụ thể, đo lại scaling efficiency sau tối ưu.
Ngày 343: Viết Báo Cáo Kỹ Thuật
Mục tiêu: Tổng kết Project 4 thành tài liệu chuyên nghiệp.
Lý thuyết: Ôn lại toàn bộ quá trình Ngày 339-342.
Thực hành: Viết báo cáo đầy đủ: chiến lược song song hoá đã chọn và lý do, số liệu scaling efficiency trước/sau tối ưu, bài học kinh nghiệm rút ra.
Project 5 - Production ML Platform Hoàn Chỉnh (Ngày 344 - 349)
Ngày 344: Thiết Kế Kiến Trúc Tổng Thể (ADR)
Mục tiêu: Có tài liệu thiết kế chuyên nghiệp trước khi bắt tay xây dựng - đúng quy trình 1 senior engineer thực thụ.
Lý thuyết: ADR (Architecture Decision Record) - tài liệu ghi lại quyết định kiến trúc quan trọng, lý do lựa chọn, và các phương án đã cân nhắc nhưng không chọn.
Thực hành: Viết ADR cho ML Platform sẽ xây: các thành phần (K8s, MLflow, DVC, Model Registry, Serving, CI/CD, Monitoring), lý do chọn từng công cụ cụ thể dựa trên kiến thức đã học ở Giai đoạn 10.
Ngày 345: Setup K8s Cluster, MLflow, DVC
Mục tiêu: Dựng nền tảng hạ tầng cơ bản.
Lý thuyết: Ôn lại setup K8s (Giai đoạn 10, Ngày 292), MLflow (Ngày 266), DVC (Ngày 270).
Thực hành: Setup toàn bộ 3 thành phần này trong cùng 1 môi trường (local cluster hoặc cloud), verify chúng hoạt động và giao tiếp được với nhau.
Ngày 346: CI/CD Pipeline & Model Registry Integration
Mục tiêu: Tự động hoá quy trình từ code commit tới model được đăng ký.
Lý thuyết: Ôn lại CI/CD cho ML (Giai đoạn 10, Ngày 299), Model Registry (Ngày 271-272).
Thực hành: Viết pipeline CI/CD tự động: chạy test → train (hoặc validate model có sẵn) → nếu đạt ngưỡng metric → tự động đăng ký vào Model Registry.
Ngày 347: Serving (vLLM) & Monitoring/Observability
Mục tiêu: Có endpoint inference production-grade với đầy đủ khả năng giám sát.
Lý thuyết: Ôn lại vLLM (Giai đoạn 10, Ngày 283-284), structured logging/tracing (Ngày 300-301).
Thực hành: Deploy model từ Registry (Ngày 346) bằng vLLM lên K8s, tích hợp logging/tracing, kết nối với dashboard giám sát (vd Grafana nếu có điều kiện).
Ngày 348: Canary Deployment & A/B Testing
Mục tiêu: Có khả năng deploy model mới an toàn, giảm rủi ro khi update production.
Lý thuyết: Canary deployment - route 1 phần nhỏ traffic sang model mới trước khi chuyển hoàn toàn, theo dõi metric để phát hiện vấn đề sớm; A/B testing - so sánh 2 phiên bản model bằng cách chia traffic ngẫu nhiên và đo metric nghiệp vụ (không chỉ metric ML thuần).
Thực hành: Cấu hình canary deployment trên K8s (dùng service mesh đơn giản hoặc chia traffic bằng label selector), thử deploy 1 phiên bản model "mới" (giả lập) theo canary, quan sát metric trước khi chuyển 100% traffic.
Ngày 349: End-to-End Test Toàn Bộ Platform
Mục tiêu: Verify toàn bộ hệ thống hoạt động liền mạch từ đầu tới cuối.
Lý thuyết: Ôn lại toàn bộ pipeline: code commit → CI/CD → train/validate → registry → canary deploy → serving → monitoring.
Thực hành: Chạy thử toàn bộ luồng end-to-end với 1 thay đổi model thực tế (vd model fine-tune mới từ Project 3), verify mọi bước tự động hoạt động đúng, ghi nhận lại thời gian từ commit tới production.
Ngày 350: Tài Liệu Kiến Trúc Cuối Cùng & Demo
Mục tiêu: Có sản phẩm hoàn chỉnh trình bày được như một kỹ sư senior.
Lý thuyết: Tổng hợp lại toàn bộ 350 ngày.
Thực hành: Hoàn thiện tài liệu kiến trúc (cập nhật ADR ngày 344 với các quyết định thực tế đã đưa ra), quay demo hệ thống, viết retrospective: điều gì sẽ làm khác nếu bắt đầu lại.
Checkpoint Cuối Cùng - Toàn Bộ Lộ Trình
Sau 350 ngày, tự đánh giá lại bằng chính 8 mục tiêu đã đặt ra từ đầu lộ trình:
[ ] Xây dựng model từ đầu bằng PyTorch và TensorFlow
[ ] Hiểu toán học phía sau Deep Learning
[ ] Hiểu autograd, computation graph, backpropagation
[ ] Đọc source code framework ở mức khá sâu
[ ] Tối ưu GPU, distributed training, mixed precision
[ ] Debug training instability
[ ] Deploy production-grade trên cloud/Kubernetes
[ ] Thiết kế MLOps pipeline hoàn chỉnh và đọc/triển khai paper mới