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

So sánh Go và Python cho LLM Gateway: Kết quả đo lường thực tế

Hacker News LLM· coylone· 4/11/2026general

Đường dẫn bài viết: https://blog.ai-process.dev/2026/10/26/go-vs-python-llm-gateway/ Đường dẫn bình luận: https://news.ycombinator.com/item?id=50369282 Điểm: 3 Số bình luận: 0

Ngày 26/10/2026 · Thời gian đọc: 10 phút · #architecture #performance #golang #ktms #benchmarks So sánh Go và Python trong xây dựng cổng kết nối LLM: Kết quả đo kiểm thực tế Thử nghiệm đo kiểm có khả năng tái lập giữa KTMS (Go) với LiteLLM Proxy (Python) và tám cổng kết nối tự lưu trữ (self-hosted) khác trên cùng cấu hình phần cứng đám mây: độ trễ phát sinh, thời gian nhận mã đầu tiên (time to first token), thông lượng, bộ nhớ, CPU và thời gian khởi động. Python là ngôn ngữ tiêu chuẩn trong lĩnh vực học máy, do đó hầu hết các đơn vị phát triển đều ưu tiên sử dụng cổng kết nối viết bằng Python. Tuy nhiên, hệ thống cổng kết nối LLM tự lưu trữ Keystone. The Model Switchboard. (KTMS) được xây dựng bằng ngôn ngữ Go. Bản chất của cổng kết nối không phải là vận hành các mô hình, mà là điều phối dữ liệu giữa các dịch vụ nội bộ và nhà cung cấp mô hình; đây thuần túy là bài toán về xử lý mạng. Nhận định “Go nhẹ hơn” là điều dễ phát biểu nhưng khó chứng minh. Vì vậy, một môi trường đo kiểm có khả năng tái lập đã được thiết lập để so sánh KTMS với LiteLLM Proxy trên cùng phần cứng, sau đó mở rộng đối chuẩn với tám cổng kết nối tự lưu trữ khác. Bài viết này trình bày chi tiết về các thông số đo lường, lỗi kỹ thuật được phát hiện trong mã nguồn qua quá trình thử nghiệm và giới hạn của các số liệu thu được. 1. Bản chất hoạt động của một cổng kết nối Cổng kết nối LLM nằm trên lộ trình tiếp nhận của mọi yêu cầu gọi mô hình: Hệ thống bị giới hạn bởi tác vụ vào/ra (I/O-bound). Cổng kết nối đảm nhiệm việc xác thực, định tuyến, áp dụng hạn mức, chuyển đổi giao thức (gRPC sang HTTP), chuyển tiếp yêu cầu và truyền phát dữ liệu (stream) phản hồi ngược lại. Toàn bộ các tác vụ này không đòi hỏi tài nguyên tính toán chuyên sâu. Duy trì kết nối mở. Phản hồi dạng luồng (streaming) giữ kết nối liên tục trong toàn bộ thời gian mô hình sinh dữ liệu; do đó, năng lực xử lý đồng thời mang tính quyết định hơn tốc độ yêu cầu đơn thuần. Tối thiểu hóa độ trễ bổ sung. Độ trễ của mô hình thường lên tới hàng trăm mili-giây trở lên, do đó độ trễ phát sinh từ cổng kết nối phải ở mức không đáng kể. Vận hành liên tục trên mọi môi trường. Các môi trường thử nghiệm (staging), xem trước (preview) và sản xuất (production) đều vận hành một bản sao, khiến mức tiêu hao tài nguyên ở trạng thái nhàn rỗi bị nhân lên nhiều lần. Các cổng kết nối viết bằng Python như LiteLLM hoạt động dựa trên FastAPI và Uvicorn. Để khai thác nhiều lõi vi xử lý, hệ thống buộc phải khởi chạy nhiều tiến trình con (worker processes) do hạn chế từ cơ chế khóa thông dịch viên toàn cục (Global Interpreter Lock - GIL). Mỗi tiến trình con nạp riêng một bản sao của trình thông dịch, các bộ SDK của nhà cung cấp và mô hình dữ liệu. Ngược lại, dịch vụ viết bằng Go chỉ vận hành trên một tiến trình duy nhất: môi trường thực thi tự điều phối các luồng goroutine trên toàn bộ các lõi và dùng chung một tập hợp nhóm kết nối (connection pools). 2. Môi trường đo kiểm Toàn bộ hệ thống đo kiểm được công khai mã nguồn mở tại ktms/bench và có thể thực thi lại chỉ bằng một câu lệnh. Công cụ Terraform sẽ khởi tạo một mạng cô lập cùng hai máy ảo (VM); tập lệnh sẽ tiến hành toàn bộ bài kiểm thử và sau đó tự động giải phóng tài nguyên. runner VM gateway VM (private network) ┌──────────┐ HTTP ┌────────────────────────────────────────┐ │ k6 │ ────────▶ │ KTMS ──────┐ │ │ │ │ LiteLLM ───┼──▶ mock OpenAI upstream │ └──────────┘ │ (direct) ──┘ │ └────────────────────────────────────────┘ Phần cứng: Sử dụng cấu hình Google Cloud c3-standard-4 (4 vCPU, 16 GB RAM, x86_64) cho máy ảo cổng kết nối, cùng một máy ảo thứ hai có cấu hình tương đương dành riêng cho bộ sinh tải, bảo đảm k6 không cạnh tranh tài nguyên CPU với cổng kết nối. Phiên bản phần mềm: KTMS được biên dịch từ mã nguồn kèm bản sửa lỗi nêu tại Mục 4; LiteLLM phiên bản v1.106.0 (phát hành trước bản v1.107.0 từng ghi nhận lỗ hổng bảo mật, phiên bản không được đưa vào thử nghiệm) với 4 tiến trình con Uvicorn (tương ứng một tiến trình trên mỗi lõi), chỉ kích hoạt khóa chính (master key), không sử dụng cơ sở dữ liệu để đạt trạng thái tinh gọn nhất; công cụ kiểm thử tải k6 phiên bản 2.3.0. Hệ thống đầu lên (Upstream): Một dịch vụ giả lập (mock) gọn nhẹ viết bằng Go mô phỏng API Chat Completions của OpenAI với các phản hồi cố định và độ trễ có thể tùy biến. Việc sử dụng dịch vụ từ các nhà cung cấp thực tế sẽ tạo ra độ trễ dao động hàng trăm mili-giây, làm mất tính chính xác của các lần đo. Dịch vụ giả lập này thực hiện đếm số lượt yêu cầu tiếp nhận, chứng minh không có phản hồi nào được trả về từ bộ nhớ đệm (cache) của cổng kết nối. Mốc đối chuẩn (Baseline): Mọi kịch bản đều được đo thêm một lượt không qua cổng kết nối (gọi trực tiếp - “direct”), theo đó “độ trễ phát sinh” được tính bằng độ trễ qua cổng kết nối trừ đi độ trễ gọi trực tiếp. Đo kiểm tuần tự: Các cổng kết nối còn lại đều được dừng hoạt động trước khi bắt đầu mỗi đợt chạy thử nghiệm. Bộ nhớ: chỉ tính cgroup RSS của vùng chứa cổng kết nối (gateway container). KTMS cần thêm Postgres và Redis, song các thành phần này không được tính vào. LiteLLM ở chế độ này không cần cả hai thành phần trên. Quy trình thử nghiệm toàn diện được tiến hành hai lần. Các thông số về độ trễ, bộ nhớ, CPU và thông lượng tối đa có mức sai lệch trong khoảng 10% giữa các lần chạy đối với từng cổng kết nối; ngoại lệ duy nhất là chỉ số p99 của LiteLLM. Các biểu đồ thể hiện giá trị trung bình của cả hai lần thử nghiệm. 3. Kết quả Độ trễ phát sinh Các yêu cầu không truyền luồng (non-streaming) ở mức ổn định 200 RPS gửi tới máy chủ đầu nguồn (upstream) có tốc độ phản hồi tức thì. KTMS làm tăng khoảng 0,6 ms ở giá trị trung vị và khoảng 1,1 ms ở mức p99. LiteLLM làm tăng khoảng 8,5 ms ở giá trị trung vị, và mức p99 dao động từ 27 ms ở lần chạy này lên 229 ms ở lần chạy khác; do đó, giá trị trung bình trên biểu đồ chỉ mang tính chất tham khảo tương đối. Thời gian phản hồi mã đầu tiên (Time to First Token) 50 luồng đồng thời, mỗi luồng gồm 20 khối dữ liệu (chunk) được gửi cách nhau 15 ms. Cả hai cổng kết nối đều chuyển giao đầy đủ từng khối dữ liệu của mọi luồng. KTMS chuyển tiếp mã đầu tiên khoảng 0,7 ms sau khi nhận được từ máy chủ đầu nguồn. LiteLLM mất khoảng 160 ms. Hệ thống này không gộp các khối dữ liệu: toàn bộ luồng truyền chỉ bắt đầu muộn hơn và kết thúc chậm hơn tương ứng khoảng 160 ms. Thông lượng Lưu lượng yêu cầu tăng dần từ 250 lên 4.000 RPS theo từng giai đoạn 20 giây, với thời gian phản hồi đầu nguồn là 10 ms. Một giai đoạn được coi là duy trì thành công khi có ít nhất 95% lưu lượng yêu cầu được xử lý và tỷ lệ lỗi dưới 1%. KTMS đáp ứng được mọi giai đoạn thử nghiệm, bao gồm cả mức cao nhất là 4.000 RPS. Chỉ số p99 của hệ thống này duy trì ở mức 13 ms khi tải đạt tới 2.000 RPS (kết nối trực tiếp: 11 ms) và tăng lên 26–43 ms ở mức 4.000 RPS. LiteLLM duy trì được ở mức 250 RPS. Ở mức 500 RPS, một phần ba số yêu cầu đã thất bại, và từ mức 1.000 RPS trở lên, thông lượng chững lại ở mức khoảng 570 RPS trong khi một nửa số yêu cầu chạm ngưỡng thời gian chờ 5 giây của máy khách. Bộ nhớ Ở trạng thái chờ, KTMS sử dụng khoảng 7 MiB. LiteLLM sử dụng khoảng 2,5 GiB với 4 tiến trình xử lý (worker), tương đương khoảng 0,6 GiB cho mỗi worker. Trong quá trình thử nghiệm tải duy trì 5 phút ở mức 200 RPS, KTMS duy trì ở mức khoảng 20 MiB và LiteLLM ở mức khoảng 2,9 GiB, cả hai đều không có hiện tượng tăng dần dung lượng. KTMS đạt mức cao nhất là 41–46 MiB trong toàn bộ quá trình thử nghiệm, bao gồm cả mức 4.000 RPS, thấp hơn nhiều so với giới hạn 512 MiB trong Helm chart. Biểu đồ chủ ý sử dụng thang đo tuyến tính. Các cột dữ liệu của KTMS rất khó nhìn thấy, và đó phản ánh đúng kết quả thực tế. CPU Trong suốt quá trình thử nghiệm tải duy trì, KTMS tiêu tốn khoảng 0,63 giây thời gian CPU cho mỗi 1.000 yêu cầu. LiteLLM tiêu tốn khoảng 9,7 giây, cao gấp 15 lần. Đây là chỉ số quyết định số lượng lõi (core) cần thiết cho một mức lưu lượng cụ thể. Thời gian khởi động Từ thời điểm thực hiện lệnh docker start đến khi yêu cầu đầu tiên được phản hồi qua cổng kết nối, KTMS mất khoảng 170 ms và LiteLLM mất khoảng 32 giây. Thời gian này bao gồm cả quá trình khởi động container, và cơ sở dữ liệu của KTMS đã được hoàn tất chuyển đổi (migration). Dung lượng tệp hình ảnh (image) cũng có sự chênh lệch tương tự. Đối với hệ điều hành linux/amd64, tệp slim image của KTMS là

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