Bỏ qua tới nội dung chính
Quay lại tin tức

Mô hình ngôn ngữ lớn Llama 2 trên DOS (2025)

Hacker News LLM· userbinator· 9/7/2026general

URL bài viết: https://yeokhengmeng.com/2025/04/llama2-llm-on-dos/ URL bình luận: https://news.ycombinator.com/item?id=48840660 Điểm: 2 Bình luận: 0

Llama 2 LLM trên DOS Ngày 15/4/2025 7 phút đọc Bạn đã bao giờ nghĩ đến việc chạy một mô hình ngôn ngữ lớn (LLM) cục bộ trên một máy tính cổ điển chạy DOS chưa? Giờ đây, điều đó đã trở thành hiện thực! Bản trình diễn Video này cho thấy ứng dụng khách DOS Llama 2 LLM đang chạy trên 2 máy tính DOS cổ điển. Chạy trên Thinkpad T42 (2004) và Toshiba Satellite 315CDT (1996). CPU của chúng lần lượt là Pentium M 735 1.7 Ghz và Pentium MMX 200Mhz. Chạy trên FreeDOS 1.4 trên Thinkpad X13 Gen 1 (2020) với Core i5-10310U 1.7Ghz. Mọi thứ đều là mã nguồn mở với tệp thực thi có sẵn tại đây: https://github.com/yeokm1/dosllam2 Bối cảnh 2 năm trước, tôi đã viết một ứng dụng khách DOS ChatGPT và nhiều người đam mê máy tính cổ điển trong cộng đồng đã viết các ứng dụng khách tương tự cho các nền tảng cổ điển khác. Tất cả đều gặp một vấn đề tương tự, đó là sự phụ thuộc vào một dịch vụ từ xa. Vậy còn việc chạy mọi thứ cục bộ thì sao? Quan niệm thông thường cho rằng việc chạy LLM cục bộ sẽ yêu cầu các máy tính có thông số kỹ thuật hiệu suất cao, đặc biệt là GPU với nhiều VRAM. Nhưng điều này có thực sự đúng không? Năm 2023, chuyên gia học máy nổi tiếng Andrej Karpathy đã phát hành dự án mã nguồn mở llama2.c của mình, cho phép suy luận các mô hình Llama 2 của Meta chỉ với một tệp C duy nhất. Các nhà phát triển khác sau đó đã chuyển dự án của ông để chạy trên nhiều nền tảng, bao gồm một số nền tảng cổ điển như Windows 98 và Powerbook G4. Thậm chí có người còn chuyển nó để chạy trên một bộ vi điều khiển. Điều này đã truyền cảm hứng cho tôi suy nghĩ, liệu điều tương tự có thể được thực hiện cho một nền tảng cũ hơn nữa như DOS không? Dựa trên video trình diễn và ảnh chụp màn hình, rõ ràng là tôi đã làm được điều này, vì vậy bài đăng trên blog này sẽ cho thấy cách tôi đã làm. Chi tiết kỹ thuật Mã gốc llama2.c được viết trong một tệp C duy nhất được thiết kế để suy luận chỉ các mô hình fp32 của kiến trúc Llama-2. Kho lưu trữ này vẫn quan tâm đến hiệu quả, nhưng không phải bằng mọi giá để đánh đổi sự đơn giản, dễ đọc hoặc khả năng di động. https://github.com/karpathy/llama2.c Để dễ dàng kiểm tra các mô hình nhỏ hơn, Karpathy đã huấn luyện một số mô hình nhỏ trên tập dữ liệu TinyStories chỉ có kích thước 260K, 15M, 42M và 110M. Điều này nhằm cho phép một mức độ chức năng LLM cơ bản trên các hệ thống hạn chế tài nguyên. llama2.c mặc dù được viết với mục đích di động, nhưng vẫn có một số thách thức khi đưa cơ sở mã hoạt động trên các hệ thống cổ điển. Biên dịch và DOS Extender Trình biên dịch tôi chọn là Open Watcom v2 (OWC). Tôi đã sử dụng nó vì tôi đã quen thuộc với nó khi sử dụng nó cho ứng dụng khách DOS ChatGPT của mình. OWC cung cấp một IDE GUI nhưng tôi thích sử dụng Makefile để giữ cho dự án tương đối nhẹ và dễ quản lý hơn. Đây là Makefile của OWC mà tôi đã sử dụng để biên dịch dự án của mình: TARGET = dosllam2 OBJS = dosllam2.obj CFLAGS = -za99 LDFLAGS = SYSTEM dos32a NAME $(TARGET) all: clean $(TARGET).exe $(TARGET).obj: dosllam2.c wcc386 $(CFLAGS) dosllam2.c $(TARGET).exe: $(OBJS) wlink $(LDFLAGS) FILE $(OBJS) Chuỗi công cụ biên dịch sử dụng wcc386 và wlink. Tôi đã sử dụng -za99 để bật hỗ trợ C99 nếu không nó sẽ trở lại C90. Sự chú ý đặc biệt được dành cho cờ dos32a. Đối với hầu hết các chương trình DOS, bạn thường có thể biên dịch cho 2 chế độ điển hình: Kiến trúc 16-bit truyền thống tương thích với Intel 8088 được sử dụng trong IBM PC đầu tiên Hỗ trợ bộ mở rộng DOS 32-bit cho CPU Intel 386 trở lên Do mã nguồn llama2.c được viết cho các hệ thống hiện đại tối thiểu 32-bit, tôi phải chọn phương án thứ hai. Yêu cầu bộ nhớ ngay cả đối với các LLM (mô hình ngôn ngữ lớn) nhỏ nhất cũng đòi hỏi một hệ thống ít nhất 32-bit. Một bộ mở rộng DOS 32-bit phổ biến được sử dụng trong kỷ nguyên DOS là DOS/4G. Bộ mở rộng này cho phép các chương trình truy cập bộ nhớ mở rộng vượt quá 640KB bộ nhớ thông thường và Vùng bộ nhớ trên (Upper Memory Area) bằng cách chuyển CPU sang chế độ bảo vệ 32-bit. Một trường hợp sử dụng rất phổ biến là các trò chơi yêu cầu nhiều bộ nhớ. Các ví dụ nổi tiếng sử dụng bộ mở rộng là Doom và Descent. OWC hỗ trợ DOS/4G như một lựa chọn bộ mở rộng cũng như một bộ mở rộng mới hơn và mã nguồn mở khác là DOS/32 của Narech Koumar phát hành năm 2006. Bộ mở rộng này có thể được nhúng vào chương trình của bạn dưới dạng thời gian chạy hoặc chạy riêng biệt. Dù bằng cách nào, hầu hết các bộ mở rộng DOS sẽ hiển thị một biểu ngữ khởi động như trên. Nỗ lực chuyển đổi Mã nguồn llama2.c gốc vẫn giả định một trình biên dịch C có các tính năng khá hiện đại. Mặc dù dự án OWC vẫn đang được duy trì, nhưng tôi đã phải thực hiện một chút nỗ lực chuyển đổi để mã có thể biên dịch được. Các phép toán dấu phẩy động Quá trình suy luận đòi hỏi sử dụng nhiều phép toán dấu phẩy động mà OWC không hỗ trợ tốt. #define sqrtf(x) ((float)sqrt((double)(x))) #define powf(x, y) ((float)pow((double)(x), (double)(y))) #define cosf(x) ((float)cos((double)(x))) #define sinf(x) ((float)sin((double)(x))) #define expf(x) ((float)exp((double)(x))) Vì vậy, tôi phải định nghĩa một số macro sử dụng các hàm double hiện có. Ánh xạ bộ nhớ Các trình biên dịch hiện đại hỗ trợ các hàm mmap hoặc các hàm tương tự cho phép ánh xạ các tệp trong bộ nhớ lưu trữ vào bộ nhớ. Nội dung của tệp không được đọc toàn bộ vào bộ nhớ cùng một lúc mà được tải lười biếng (lazy-loaded), tức là chỉ những phần cần thiết mới được đọc khi cần, giúp tăng tốc độ sử dụng các tệp đặc biệt lớn. OWC không hỗ trợ điều này, do đó tôi phải thay thế tất cả các lệnh gọi ánh xạ bộ nhớ để tải toàn bộ tệp LLM vào bộ nhớ. Điều này có tác dụng làm tăng thời gian tải ban đầu. Tôi đã cân nhắc việc tự viết một phiên bản mmap của riêng mình. Tuy nhiên, với trường hợp sử dụng LLM, nơi mà hầu hết (nếu không phải tất cả) các trọng số cuối cùng sẽ được sử dụng, thì đó chỉ là việc trì hoãn việc tải toàn bộ tệp. Vì vậy, dễ dàng hơn nhiều khi giữ mọi thứ đơn giản và tải toàn bộ tệp cùng một lúc ngay từ đầu. Thời gian Để đo tốc độ suy luận, chương trình yêu cầu sử dụng các API thời gian: long time_in_ms() { struct timespec time; clock_gettime(CLOCK_REALTIME, &time); return time.tv_sec * 1000 + time.tv_nsec / 1000000; } Các API đó không khả dụng, do đó tôi phải thay đổi sang một cái khác. long tim

Nguồn tin: Hacker News LLM — Tác giả: userbinator. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.