Llama2.c: Suy luận Llama 2 trong một tệp C thuần túy
(github.com/karpathy)- llama2.c là một giải pháp huấn luyện và suy luận “fullstack”, huấn luyện kiến trúc Llama 2 LLM bằng PyTorch và suy luận bằng tệp C đơn giản
run.c - Trọng tâm cốt lõi là chủ nghĩa tối giản và sự đơn giản, là một triển khai mang tính giáo dục với kiến trúc Llama 2 được hard-code và chỉ gồm một tệp suy luận C thuần túy không có phụ thuộc
- Dựa trên quan điểm rằng ngay cả LLM rất nhỏ cũng có thể đạt hiệu năng mạnh nếu thu hẹp miền bài toán đủ nhiều, dự án cung cấp mô hình ví dụ dựa trên TinyStories
- Mô hình 15M tham số có dung lượng tải về khoảng 60MB và có thể chạy bằng
make runrồi./run stories15M.bin - Các mô hình 42M và 110M tham số cũng được cung cấp, và mô hình 110M được nêu rõ là có cùng kích thước với GPT-1
- Mô hình 15M tham số có dung lượng tải về khoảng 60MB và có thể chạy bằng
- Các mô hình Llama 2 của Meta cũng có thể suy luận vì kiến trúc mạng nơ-ron là như nhau, nhưng cần nhận checkpoint theo hướng dẫn của Meta rồi chuyển đổi sang định dạng llama2.c bằng
export.py- Hiện tại
run.cchỉ thực hiện suy luận fp32, nên các mô hình lớn hơn 7B có khả năng khó tải một cách thực tế trong môi trường production - Từ 13B trở lên hiện không hoạt động do integer overflow trong phép toán con trỏ, và vẫn chưa được sửa
- Hiện tại
- Suy luận lượng tử hóa int8 được triển khai trong
runq.c, sử dụng phương thức Q8_0 để lượng tử hóa các trọng số tham gia vào matmul, đồng thời các giá trị kích hoạt cũng được lượng tử hóa và giải lượng tử động trong lúc chạy- Bản export fp32 của Llama 2 7B tạo ra tệp 26GB, còn bản export lượng tử hóa version 2 tạo ra tệp 6.7GB
- Trong môi trường của tác giả với OpenMP 64 luồng, fp32 chạy ở 4.6 tok/s còn int8 là 14 tok/s, giúp giảm kích thước checkpoint 4 lần và tăng tốc khoảng 3 lần
- Cách sử dụng gồm chạy suy luận C, nhập prompt, điều khiển lấy mẫu temperature và top-p, chạy chế độ chat, và chỉ định tokenizer tùy chỉnh
- Ví dụ chạy có dạng
./run stories42M.bin -t 0.8 -n 256 -i "One day, Lily met a Shoggoth" - Mô hình chat chạy bằng cờ
-m chatnhư./run llama2_7b_chat.bin -m chat - Tokenizer tùy chỉnh được export sang định dạng
.binbằngtokenizer.pyrồi chỉ định bằng cờ-z
- Ví dụ chạy có dạng
- Các mô hình trên Hugging Face dùng kiến trúc Llama 2 có thể được export sang tệp
.binbằng cờ--hfcủaexport.py - Quy trình huấn luyện tiếp nối từ tải xuống và tiền token hóa TinyStories, chạy
train.py, rồi export mô hình và suy luận bằng C- Ví dụ TinyStories mặc định hiện là ví dụ dataset duy nhất được cung cấp
- Việc huấn luyện tokenizer tùy chỉnh sử dụng
sentencepiece, với ví dụ dùng thiết lập--vocab_size=4096
- Các bản build liên quan đến hiệu năng được chia thành
make run,make runfast,make runomp, trong đó bản build OpenMP kích hoạt#pragma omp parallel forbên trong matmul và attention để chia công việc vòng lặp cho nhiều bộ xử lý - Hướng dẫn build theo nền tảng được cung cấp cho Windows, Centos 7, Amazon Linux 2018 và Mac
- Windows dùng
build_msvc.bathoặcmake win64 - Centos 7 và Amazon Linux 2018 dùng
make rungnuhoặcmake runompgnu - Bản build OpenMP trên Mac dùng clang từ brew rồi chạy
make runomp CC=/opt/homebrew/opt/llvm/bin/clang
- Windows dùng
- Kiểm thử cung cấp
pytestvà bài test Cmake testcc, còntest_all.pychạy 200 bước forward trong C và Python để so sánh với đầu ra kỳ vọng đã biết - Mục tiêu của dự án là duy trì một triển khai tham chiếu đơn giản gồm 2 tệp
.pydễ đọc cho mã huấn luyện và mã suy luận C, không hướng đến framework phức tạp hay quá nhiều tùy chọn - Giấy phép là MIT
1 bình luận
Ý kiến Hacker News
Thấy bài này trên HN khá thú vị :) checkpoint gốc chạy nhanh hơn kỳ vọng rất nhiều trên MacBook Air M1 khi biên dịch với
-O3, đạt 100 tok/s, nên giờ đang huấn luyện một mô hình 44M lớn hơnCó vẻ vẫn sẽ chạy được ở chế độ tương tác, và thậm chí có cảm giác biết đâu mô hình Llama 7B cũng có thể với tới
nanoGPTmột chút để thử tiền huấn luyện một mô hình 12M trên 2GB dữ liệu do GPT-4 tạo từ TinyStories, và kết quả khá bất ngờSau đó mình cho nó thích nghi thêm với Wikipedia, và nó trở thành một cỗ máy tạo ra nội dung nghe có vẻ hợp lý nhưng vô nghĩa, thông minh hơn rất nhiều và nhỏ hơn rất nhiều so với mô hình n-gram được làm trơn. Có vẻ các LLM nhỏ sẽ trở thành xu hướng chủ đạo ở nhiều lĩnh vực, và mục tiêu tiếp theo là thu nhỏ Llama2 7B xuống 10~100M mà không làm nó ngốc đi quá nhiều
Thuê instance GPU ở mấy nơi như Linode đắt hơn rất nhiều so với máy chủ web app thông thường, nên mình muốn biết liệu đây có phải là vùng hoàn toàn bất khả thi, hay kiểu tiếp cận này hoặc cách nào khác vẫn là hướng đi thực tế
Georgi Gerganov, người nổi tiếng với llama.cpp, có một phiên bản chạy trong trình duyệt bằng Emscripten: https://ggerganov.com/llama2.c/
Chuỗi Twitter đang được cập nhật ở https://twitter.com/ggerganov/status/1683174252990660610
Cả bản gốc lẫn bản này đều thực sự rất hay, và dù gần giống một bản chứng minh khái niệm dùng mô hình cực nhỏ, LLM ưu tiên chạy cục bộ vẫn đặc biệt hấp dẫn. Ý tưởng có thể xây dựng web app với suy luận cục bộ rất đáng thích
Nếu tiến tới tối ưu hóa, nghiên cứu mô hình nhỏ hơn, tải xuống từng phần và tận dụng WebGPU, đây có thể là điểm khởi đầu cho một cách mới để tạo ứng dụng riêng tư dựa trên LLM cục bộ. Có thể sẽ khó đạt được năng lực như các LLM được host trên cụm GPU cao cấp quy mô lớn, nhưng cách tiếp cận này mở ra rất nhiều trường hợp sử dụng
Ví dụ, nó bắt đầu bằng “Once upon a time...”, trông như câu chuyện về Lily và Timmy, rồi biến thành đầu ra hỏng hoàn toàn với những đoạn như “Butterfly would pauseWhy”, “TextField”,
querySelector,HttpRequestvà các mảnh ngôn ngữ khác nhau bị trộn lẫnVới ai quan tâm thì cũng có bản Rust. Ở chế độ release chạy được khoảng 106 tokens/second
https://github.com/garrisonhess/llama2.c/blob/517a1a3e487f31...
Bản không chạy trên web hỗ trợ GPU đầy đủ, nhưng hoàn toàn không tối giản
Đôi lúc điều đó còn phân tán nỗ lực của cộng đồng trong việc cải thiện dự án
Có vẻ không nhiều người hiểu đây là bước đi táo bạo đến mức nào
Andrej đang nhận thù lao rất lớn từ OpenAI(MSFT), nhưng vẫn giúp Apple, Facebook và quan trọng hơn là phong trào mã nguồn mở. Dù vậy, cũng khó mà chèn ép được anh ấy, vì nếu thế thì anh ấy có thể chuyển thẳng sang Tesla hoặc xAI
Mình cảm thấy Llama-2 bị lọc an toàn quá mức đến nỗi không thể dùng cho công việc sáng tạo: https://i.imgur.com/GFY0wSL.png
Tuy nhiên hiện tượng này chỉ tái hiện phần nào khi gửi như tin nhắn thứ hai trên Llama2-70b-chat TGI Hugging Face, nên có thể có điều gì đó kỳ lạ ở cách viết prompt dẫn đến hành vi này. Mình vẫn chưa thể tự chạy mô hình để điều tra thêm
Chat/instruct có ưu điểm là dễ phân phối cho người dùng bên thứ ba, prompt đơn giản và có sẵn các rào chắn an toàn, nhưng để tự dùng thì nó kém xa mô hình tiền huấn luyện. Ở điểm này Llama 2 có thể có lợi thế hơn OpenAI, vì OpenAI dường như đã bỏ các mô hình GPT-3 tiền huấn luyện và từ nay chỉ cung cấp mô hình chat
Tôi không muốn kiểu kéo an toàn đó. Hạn chế những thứ chạy trên máy chủ của họ thì được, nhưng đừng đưa cho tôi một mô hình mà tôi không thể chỉnh sửa và dùng theo ý mình trên chính máy tính của tôi
Andrej đã đăng chi tiết hơn ở đây: https://twitter.com/karpathy/status/1683143097604243456?s=46...
Nhân tiện, nếu bạn quan tâm đến mảng này, đoạn mã này có thể được build gọn gàng bằng WASI SDK và chạy trong runtime Wasm mà không cần sửa đổi
Tò mò không biết cần bao nhiêu bộ nhớ để chạy mạng nơ-ron
Chỉ cần đọc hai lớp đầu từ đĩa và tính giá trị kích hoạt của mọi nút, rồi bỏ lớp thứ nhất, đọc lớp thứ ba và tính tiếp, sau đó bỏ lớp thứ hai, cứ như vậy là đủ chứ? Nếu vậy thì có phải chỉ cần đủ bộ nhớ để chứa hai lớp không?
Tóm lại, RAM tối đa thay đổi theo phương pháp lượng tử hóa, và xấp xỉ là mô hình 7B cần 4~8GB, 13B cần 8~15GB, 30B cần 13~33GB, còn 70B nằm trong khoảng 31~75GB
Một ý nghĩ chợt đến là, hiện tại LLM trả về một phân phối xác suất, rồi một bộ lấy mẫu ngẫu nhiên chọn một phần tử và gắn nó vào đầu ra, sau đó lặp lại
Thay vào đó, liệu có thể để bộ ngẫu nhiên chọn ra N token gần đúng với phân phối, cho LLM tạo ra N phân phối mới, rồi kết hợp chúng theo cách nào đó và lại chọn N token từ phân phối kết hợp không?
Có thể xem ví dụ tại https://huggingface.co/docs/transformers/internal/generation...
Dù vậy tôi không biết phải làm điều đó thế nào
Tất nhiên, mỗi lần sinh token sẽ cần lượng tính toán gấp N lần. Có thể chọn N phần tử đứng đầu, hoặc nếu cần thì áp dụng điều chỉnh nhiệt độ lên logits để lấy mẫu N phần tử
Đây là để phục vụ giáo dục à? Nhìn vào thành công của llama.cpp và dự án này, có vẻ như ngành đang đi theo hướng có mã nguồn riêng cho từng mô hình được phát hành, thay vì các framework đa dụng như PyTorch, TensorFlow hay ONNX Runtime
Và không phải vậy. Trái với tên gọi, llama.cpp không chỉ hỗ trợ llama. Nó cũng không hoàn toàn tùy biến riêng, mà được xây dựng trên thư viện/framework tensor
ggmlmang tính tổng quát hơnTuy nhiên, khi tìm ra mô hình hoạt động tốt, các phát triển đó thường được đưa vào phiên bản framework tiếp theo. Vì vậy TensorFlow mới có các thành phần cơ bản như CNN, GRU, TransformerEncoder, đồng thời cũng có các triển khai chuyên biệt cho phần cứng nhất định để đổi bớt tính tổng quát lấy tốc độ