- MicroGPT là một bản triển khai tối giản của mô hình GPT được viết bằng 200 dòng mã Python thuần, được thiết kế để giúp hiểu trực quan cấu trúc cốt lõi của mô hình ngôn ngữ lớn
- Mô hình được huấn luyện trên bộ dữ liệu 32.000 tên người để tạo ra các tên mới, đồng thời trực quan hóa theo từng bước quá trình token hóa, dự đoán, tính loss và backpropagation
- Bài viết giải thích các thành phần chính của GPT như Softmax, Cross-Entropy Loss, Backpropagation, Embedding, Attention cùng với mã nguồn
- Trong quá trình huấn luyện, mô hình dùng optimizer Adam để giảm loss dần dần, sau đó tạo ra nhiều tên khác nhau thông qua điều chỉnh nhiệt độ (Temperature Sampling)
- Đây là tài liệu học tập ở dạng đơn giản hóa thuật toán cốt lõi của các mô hình lớn như ChatGPT, giúp hiểu nguyên lý vận hành bên trong của LLM
Tổng quan về MicroGPT
- Dựa trên script Python 200 dòng do Andrej Karpathy viết, bài viết giải thích trực quan quá trình huấn luyện và suy luận của mô hình GPT
- Được triển khai chỉ bằng Python thuần, không dùng thư viện bên ngoài
- Giữ nguyên các thuật toán nền tảng của mô hình ngôn ngữ lớn như ChatGPT
- Bài viết trình bày từng bước của mô hình bằng cách tiếp cận trực quan, thân thiện với người mới bắt đầu
Bộ dữ liệu và mục tiêu huấn luyện
- Sử dụng 32.000 tên người (ví dụ: emma, olivia, ava, v.v.) làm dữ liệu huấn luyện
- Mỗi tên được xem như một tài liệu, và mô hình học các mẫu ký tự trong tên
- Sau khi huấn luyện, mô hình tạo ra các tên mới như “kamon”, “karai”, “anna”, “anton”
- Mô hình học các quan hệ thống kê giữa các ký tự, độ dài tên, cũng như các mẫu ngữ âm ở đầu và cuối tên
Quá trình chuyển văn bản thành số
- Vì mạng nơ-ron chỉ xử lý số, mỗi ký tự được chuyển thành ID số nguyên
- a–z được gán 0–25, còn BOS (Beginning of Sequence) được gán là 26
- Token BOS dùng để đánh dấu điểm bắt đầu và kết thúc của tên
- tiktoken của GPT-4 token hóa theo đơn vị mảnh ký tự thay vì từng ký tự, nhưng nguyên lý là giống nhau
Dự đoán token tiếp theo
- Mô hình dự đoán ký tự tiếp theo từ ngữ cảnh đã cho
- Ví dụ: [BOS] → “e”, [BOS, e] → “m”, [BOS, e, m] → “m”, [BOS, e, m, m] → “a”
- Mỗi bước tạo ra một cặp đầu vào (ngữ cảnh) và mục tiêu (ký tự tiếp theo), cách làm này giống với ChatGPT
Softmax và tính xác suất
- Đầu ra của mô hình gồm 27 logit, sau đó được chuyển thành xác suất bằng Softmax
- Mỗi logit được lấy hàm mũ rồi chia cho tổng để tạo phân phối xác suất
- Việc trừ đi giá trị lớn nhất là bước ổn định hóa để tránh tràn số
- Kết quả Softmax biểu thị xác suất mỗi token sẽ xuất hiện tiếp theo
Tính loss: Cross-Entropy
- Độ chính xác của dự đoán được tính bằng −log(p)
- Xác suất của đáp án đúng càng cao thì loss càng thấp, và khi gần 0 thì loss tăng mạnh
- Khi p=1 thì loss bằng 0, khi p→0 thì loss tiến tới vô cùng
- Quá trình huấn luyện diễn ra theo hướng tối thiểu hóa loss này
Lan truyền ngược (Backpropagation)
- Dựa trên loss để tính mức độ ảnh hưởng của từng tham số đến sai số
- Vi phân được thực hiện thông qua đồ thị tính toán, trong đó mọi phép toán (add, multiply, exp, log, v.v.) đều là các nút
- Mỗi nút lưu đầu vào và đạo hàm cục bộ, rồi truyền gradient theo chiều ngược lại
- Ví dụ: L = a⋅b + a (a=2, b=3) → gradient của a là 4.0 (tổng của hai đường đi)
- Nguyên lý này giống với
loss.backward() của PyTorch
Embedding
- Mỗi ID token được chuyển thành vector 16 chiều để học biểu diễn ý nghĩa
- Embedding token và embedding vị trí được cộng lại để làm đầu vào
- Cùng một ký tự nhưng có thể giữ vai trò khác nhau tùy vị trí
- Sau huấn luyện, các ký tự tương tự nhau (ví dụ: nguyên âm) sẽ có vector gần nhau
Attention
- Mỗi token tạo ra các vector Query, Key, Value
- Độ liên quan được tính bằng tích vô hướng giữa Query và Key, sau đó Softmax cho ra trọng số
- Tổng có trọng số của Value được dùng làm đầu ra
- Áp dụng Causal Mask để không tham chiếu đến các token trong tương lai
- Có 4 attention head hoạt động song song và học các mẫu khác nhau
Cấu trúc GPT tổng thể
- Token đầu vào đi qua các bước sau
- Embedding + embedding vị trí
- Chuẩn hóa RMSNorm
- Multi-head attention
- Kết nối residual
- MLP (mở rộng lên 64 chiều → ReLU → thu lại còn 16 chiều)
- Kết nối residual một lần nữa rồi tính logit đầu ra
- Kết nối residual giúp ngăn gradient biến mất
- RMSNorm giữ độ lớn của activation ổn định để quá trình huấn luyện ổn định hơn
Vòng lặp huấn luyện
- Huấn luyện lặp lại 1.000 lần
- Chọn tên → token hóa → forward pass → tính loss → backpropagation → cập nhật tham số
- Sử dụng optimizer Adam
- Giúp hội tụ ổn định nhờ momentum và learning rate thích ứng
- Loss giảm từ khoảng 3.3 xuống 2.37
- Các tên được tạo ra dần chuyển từ ngẫu nhiên sang tự nhiên hơn
Suy luận (Inference) và sampling
- Sau khi huấn luyện, mô hình bắt đầu với BOS rồi lặp lại việc dự đoán token tiếp theo
- Quá trình sinh tiếp tục cho đến khi BOS xuất hiện lại
- Temperature dùng để điều chỉnh mức độ đa dạng của việc sampling
- Nhiệt độ càng thấp thì càng mang tính quyết định (trung bình hơn), càng cao thì càng sáng tạo nhưng kém ổn định
- Nhiệt độ phù hợp để tạo tên là khoảng 0.5
- Ví dụ đầu ra: “karai”
Hiệu quả và khả năng mở rộng
- MicroGPT là một bản triển khai hoàn chỉnh nhưng được đơn giản hóa của thuật toán cốt lõi GPT
- Khác biệt với ChatGPT chủ yếu chỉ là quy mô
- Thay vì 32.000 tên là hàng nghìn tỷ token, thay vì 4.192 tham số là hàng trăm tỷ tham số
- Dùng phép toán tensor trên GPU thay cho phép toán vô hướng trên CPU
- Vòng lặp cơ bản vẫn giống nhau: token hóa → embedding → attention → dự đoán → loss → backpropagation → cập nhật
Kết luận
- MicroGPT là một mô hình giáo dục giúp học trực quan nguyên lý vận hành bên trong của GPT
- Bằng cách đơn giản hóa cấu trúc phức tạp của LLM quy mô lớn, nó cho phép người học trực tiếp trải nghiệm cơ chế cốt lõi của mô hình ngôn ngữ
1 bình luận
Ý kiến trên Hacker News
Có nói rằng khi kết thúc huấn luyện, mô hình tạo ra các tên như "kamon", "karai", "anna", "anton", nhưng thực tế những cái tên này cũng đã có trong bộ dữ liệu
Có lẽ nên dùng tên khác — liên kết bộ dữ liệu
Dù nói là dành cho người mới bắt đầu, nhưng tôi không chắc có bao nhiêu người mới có thể hiểu được kiểu giải thích toán học như thế này
Ví dụ, phần giải thích công thức cross-entropy loss có cảm giác quá phức tạp
Tôi sẽ suy nghĩ lại
Điều tôi không hiểu là làm sao một mô hình đơn giản như thế này lại có thể gỡ lỗi các bài toán code bất kỳ
Tôi tò mò không biết suy luận thống kê làm thế nào lại biến thành ‘năng lực suy luận’
Dùng Claude code hằng ngày khiến giờ tôi thấy đúng là nó thực sự làm được như vậy
Cốt lõi là: “nếu luôn có thể dự đoán chính xác từ tiếp theo, thì rốt cuộc cũng có thể trả lời đúng mọi câu hỏi”
Vì vậy gần đây lĩnh vực này đang phát triển theo hướng tìm ‘đáp án đúng’ bằng các cách tiếp cận dựa trên học tăng cường như RLHF hay RLVR
Về mặt toán học, nó gần hơn với một bài toán tối ưu hóa dựa trên vi tích phân
Không phải chỉ học thống kê văn bản đơn thuần, mà là tìm một lời giải phức tạp để dự đoán token tiếp theo
Mạng nơ-ron có yếu tố thống kê, nhưng cũng còn hơn thế nữa, giống như não người
Tôi đã đọc toàn bộ bài viết, có phần hữu ích nhưng cũng mang cảm giác kiểu ‘hãy vẽ nốt phần còn lại của con cú’
Có vẻ như phần kết nối giữa các khái niệm đã bị thiếu, nhưng cách trình bày tương tác thì hay
Tôi nghĩ nên đi sâu hơn một chút
Không biết dạo này có phải đang thịnh hành việc cố tình thêm lỗi chính tả hay lỗi ngữ pháp để cho thấy bài viết không phải do LLM tạo ra hay không
Tôi thấy trong blog của Karpathy và cả bài này cũng có khá nhiều lỗi kiểu đó
Anh ấy chỉ chống đỡ dự án Full Self Driving của Elon trong thời gian dài, và cũng không ở OpenAI quá lâu
Dạo này có vẻ gần như chỉ tập trung vào code golf hoặc nghĩ ra thuật ngữ mới
Bản gốc nằm trên blog của Karpathy — liên kết bài microGPT
Có người bảo quá cơ bản, có người lại bảo quá sâu, nhưng
với người như tôi, vốn không hiểu rõ cách mô hình hoạt động, thì đây là một bài tổng quan tốt
Tôi chưa hiểu hoàn toàn, nhưng có vẻ là điểm khởi đầu tốt để bắt đầu học
Đây là một trong những hướng dẫn hữu ích nhất mà tôi từng xem
Ngay cả tôi vốn không viết code cũng bắt đầu viết code nhờ AI
Cách giải thích đơn giản và rõ ràng, rất hữu ích khi nghĩ xem nên nhập gì cho AI
Có vẻ T-Mobile đang chặn trang blog này
liên kết trang cảnh báo chặn
Đọc bài xong thì tôi hiểu việc nó xuất ra tên, nhưng vẫn thắc mắc tại sao lại dùng tạo tên làm ví dụ
Hoàn toàn có thể dùng bất kỳ loại dữ liệu nào khác