Chuyển đến nội dung chính
Hướng dẫn AI

Triển khai Qwen3.8 Flash Next 176B trên hai DGX Spark

Hướng dẫn này trình bày cách sử dụng công thức một tệp của kho lưu trữ để tải xuống, vá và triển khai Qwen3.8-Flash-Next-NVFP4 trên hai nút NVIDIA DGX Spark, đồng thời tuân thủ các giới hạn bộ nhớ hợp nhất GB10 và yêu cầu về attention thưa SM121 của mô hình.

Triển khai Qwen3.8 Flash Next 176B trên hai DGX Spark

Tổng quan

Dự án này là công thức triển khai hướng đến môi trường production để cung cấp RadixArk/Qwen3.8-Flash-Next-NVFP4 bằng SGLang. Mô hình là một mô hình mixture-of-experts được lượng tử hóa NVFP4, có khoảng 176 tỷ tham số và dung lượng 135 GB.

Tập lệnh start.sh được cung cấp phân phối mô hình trên hai hệ thống NVIDIA DGX Spark bằng tensor parallelism với TP=2. Các nút giao tiếp qua liên kết ConnectX-7 200 Gb RoCEv2 kết nối trực tiếp. Khi chạy, nút head cung cấp API tương thích với OpenAI tại 0.0.0.0:8888.

Công thức này không chỉ là một trình khởi chạy. Nó tải xuống và xác minh trọng số, đồng bộ chúng với worker, xây dựng image container đã vá trên cả hai nút, khởi động cluster và chờ API sẵn sàng. Công thức được thiết kế có tính idempotent, vì vậy khi chạy lại, nó có thể tiếp tục các lượt tải xuống bị gián đoạn, sử dụng lại bộ nhớ đệm và thay thế các container cũ.

Công Thức Cung Cấp Gì

  • Phục vụ tensor song song trên hai nút: Một DGX Spark chạy rank 0 và bộ định tuyến SGLang, trong khi hệ thống thứ hai chạy rank 1.
  • Các endpoint tương thích với OpenAI: API hỗ trợ chat, completions, đầu ra suy luận, phân tích tool call và đầu vào kết hợp văn bản với hình ảnh.
  • Ngữ cảnh dài: Độ dài ngữ cảnh mặc định là 900000 token, sử dụng việc mở rộng YaRN từ ngữ cảnh gốc 262.144 token của mô hình.
  • Giải mã suy đoán NEXTN: Các thiết lập suy đoán mặc định là 3/1/4, với giải mã bằng CUDA graph trên cả hai nút.
  • Tương thích SM121: Bản build áp dụng phương án dự phòng Triton cho đường dẫn Qwen Sparse Attention, vốn không thể biên dịch trên DGX Spark.
  • Lệnh vận hành: Tập lệnh bao gồm kiểm tra trước khi chạy, tải xuống, khởi chạy, dừng, xem trạng thái, xem log và kiểm thử smoke.

README báo cáo tốc độ 64,4 token mỗi giây cho một luồng giải mã đơn và tổng tốc độ 116,8 token mỗi giây với hai luồng trên cluster hai nút được kiểm thử. Với bốn luồng, tổng thông lượng đạt 114,1 token mỗi giây.

Vì Sao Cần Bản Vá Kernel SM121

Kiến trúc Qwen4Exp định tuyến attention qua backend Qwen Sparse Attention. Bộ phân giải flash-attention ưu tiên FA2 cổ điển và nếu không, sử dụng giao diện flash-attn-4 CuTe DSL. Trên kiến trúc SM121 của DGX Spark, phương án dự phòng này không biên dịch được do lỗi MLIR về tính tương hợp layout.

Repository giải quyết lỗi chặn khởi động này bằng cách xây dựng một image SGLang dẫn xuất có chứa phương án dự phòng attention Triton tương thích với SM121.

Context build .patch/ được tạo bao gồm qsa_fa_fallback.py, một kernel có độ dài biến đổi theo phong cách FlashDecoding, được điều chỉnh cho contract lời gọi QSA của mô hình. Kernel hỗ trợ grouped-query attention, kích thước head tối đa 256 và softmax trực tuyến. Kernel cũng đọc cu_seqlens trên thiết bị, giúp việc phát lại CUDA graph vẫn hợp lệ khi backend viết lại bảng sequence.

Trong quá trình build Docker, công thức vá qwen_sparse_attn_backend.py để phương án dự phòng Triton được chọn bất cứ khi nào is_sm100_supported() trả về false. Do đó, đường dẫn tiêu chuẩn vẫn được giữ nguyên trên các GPU trung tâm dữ liệu B100 và B200 được hỗ trợ.

Phần Cứng Và Phần Mềm Bắt Buộc

Phần cứng cluster

  • Hai hệ thống NVIDIA DGX Spark với GPU GB10, kiến trúc SM121 và bộ nhớ hợp nhất 128 GB mỗi hệ thống.
  • Các cổng ConnectX-7 được kết nối trực tiếp giữa hai máy, không qua switch.
  • Các giao diện RoCE cần thiết đang hoạt động trên cả hai nút, chẳng hạn rocep1s0f1/enp1s0f1np1 trên một nút và rocep1s0f0/enp1s0f0np0 trên nút còn lại.
  • Dung lượng lưu trữ đủ cho checkpoint khoảng 135 GB, image container, bộ nhớ đệm và dữ liệu build tạm thời.

Phần mềm trên nút head

  • Docker.
  • CLI hf của Hugging Face.
  • Token Hugging Face trong môi trường shell nếu quyền truy cập checkpoint yêu cầu xác thực.
  • Quyền truy cập SSH không cần mật khẩu từ nút head đến worker.

Cài đặt CLI Hugging Face trên nút head bằng lệnh:

pip install hf

Theo mặc định, worker được truy cập thông qua alias SSH có tên spark2. Tài khoản đăng nhập worker mặc định là cùng tên người dùng được sử dụng để chạy start.sh trên nút head. Có thể thay đổi các giả định này trong .env.

Cấu Hình Cluster Hai Nút

Clone repository trên nút head, truy cập thư mục của repository và tạo tệp cấu hình cục bộ:

git clone <this-repo>
cd <this-repo>
cp .env.example .env

Chỉnh sửa .env và xác nhận ít nhất IP RoCE của head, IP RoCE của worker và đích SSH. Các giá trị mặc định giả định những địa chỉ mạng riêng sau:

HEAD_CX7_IP=10.0.22.1
WORKER_CX7_IP=10.0.22.2
WORKER_HOST=spark2

Nếu worker sử dụng tài khoản khác, hãy đặt WORKER_USER. Để kiểm soát hoàn toàn đích SSH, hãy đặt WORKER_SSH thành một giá trị như user@host. Các biến môi trường shell được ưu tiên hơn các giá trị trong .env.

Topology dự kiến

Client kết nối đến API của nút head qua cổng 8888. Nút head chạy rank 0, máy chủ SGLang và bộ định tuyến. Rank 1 chạy trên worker. Lưu lượng NCCL được gắn cố định vào kết nối ConnectX-7 RoCEv2 trực tiếp giữa hai hệ thống.

Công thức sử dụng NCCL_NET=IB, bật phương thức truyền tải RoCE tương thích với InfiniBand và tắt NVLS cùng CUMEM cho thiết lập này. Công thức cũng có thể nạp trước bản build NCCL 2.30.7 trên host đã được staging. Tính năng này được bật theo mặc định thông qua USE_HOST_NCCL=1.

Xác Minh Môi Trường

Chạy kiểm tra trước tích hợp trước khi tải xuống mô hình:

./start.sh doctor

Lệnh doctor kiểm tra fabric, GPU, RAM, dung lượng đĩa, kết nối SSH, các cổng và các ràng buộc triển khai. Hãy khắc phục mọi vấn đề về mạng, xác thực, lưu trữ hoặc tài nguyên được báo cáo trước khi bắt đầu tải xuống tệp lớn và xây dựng image.

Tải xuống và Đồng bộ hóa Mô hình

Tải checkpoint xuống nút đầu, xác minh rồi đồng bộ hóa với nút worker:

./start.sh download

Giá trị mặc định DOWNLOAD_MODE=rsync khiến nút đầu tải các tệp xuống rồi sao chép chúng sang worker. Thao tác này có thể tiếp tục nếu bị gián đoạn. Nếu muốn mỗi máy tự tải độc lập từ Hugging Face, hãy đặt:

DOWNLOAD_MODE=direct

Không kiểm thử mô hình này bằng tùy chọn --load-format dummy của SGLang trên GB10. Theo phân tích sự cố của kho mã, trình khởi tạo dummy tạm thời chuyển đổi các tham số fp8 sang fp16. Do đó, bảng n-gram PLE fp8 51.2 GB của mô hình có thể tạo ra nhu cầu bộ nhớ tạm thời vượt quá 150 GB và khiến hệ thống có khoảng 121.7 GB DRAM hợp nhất khả dụng bị treo cứng.

Xây dựng Image Đã Vá và Bắt đầu Phục vụ

Khởi chạy triển khai hai nút bằng:

./start.sh serve

Lệnh này chạy kiểm tra trước, xác nhận weights và image đã có sẵn, xây dựng image đã vá SM121 trên cả hai nút, khởi chạy cụm TP2 và chờ API sẵn sàng. Image cục bộ được tạo có tên qwen38-flashnext-dspark:local.

Quá trình khởi động ban đầu mất khoảng mười phút vì bao gồm việc tải 135 GB weights, biên dịch JIT và thu thập CUDA graph. Theo mặc định, tập lệnh cho phép tối đa WAIT_TIMEOUT_MIN=90.

Để tự động hóa hoàn toàn lần chạy đầu tiên, hãy dùng:

./start.sh

Khi không có lệnh con, tập lệnh thực thi lần lượt doctor, download và serve.

Gửi Yêu cầu Chat Cơ bản

Sau khi máy chủ sẵn sàng, hãy gọi endpoint chat tương thích với OpenAI:

curl http://127.0.0.1:8888/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "Qwen3.8-Flash-Next-NVFP4",
    "messages": [
      {
        "role": "user",
        "content": "Explain RoCEv2 in one paragraph."
      }
    ]
  }'

Suy luận được bật theo mặc định và nội dung suy luận được truyền trực tuyến riêng. Để tắt chế độ suy nghĩ cho một yêu cầu, hãy thêm chat_template_kwargs vào phần thân JSON:

{
  "model": "Qwen3.8-Flash-Next-NVFP4",
  "messages": [
    {"role": "user", "content": "Summarize tensor parallelism."}
  ],
  "chat_template_kwargs": {
    "enable_thinking": false
  }
}

Đầu vào hình ảnh được hỗ trợ thông qua phần nội dung image_url tương thích với OpenAI tiêu chuẩn. README xác nhận rằng đầu vào kết hợp văn bản và hình ảnh đang hoạt động, mặc dù không cung cấp ví dụ hoàn chỉnh về yêu cầu có hình ảnh.

Kết nối Ứng dụng Khách Tương thích với OpenAI

Các ứng dụng hỗ trợ endpoint OpenAI tùy chỉnh có thể sử dụng URL cơ sở sau:

http://127.0.0.1:8888/v1

Mã định danh mô hình là:

Qwen3.8-Flash-Next-NVFP4

Nếu ứng dụng khách yêu cầu trường khóa API ngay cả khi endpoint cục bộ không xác thực yêu cầu, ví dụ của kho mã sử dụng dummy và tắt header xác thực. Các khả năng mô hình và thiết lập tương thích liên quan bao gồm:

  • Đã bật suy luận.
  • Đầu vào văn bản và hình ảnh.
  • Cửa sổ ngữ cảnh 900000 token.
  • Tối đa 32768 token đầu ra trong cấu hình ứng dụng khách mẫu.
  • max_tokens là trường chỉ định số token đầu ra.
  • Không hỗ trợ vai trò developer trong cấu hình tương thích mẫu.
  • Không hỗ trợ tham số reasoning-effort.

Vận hành Máy chủ

Bộ khởi chạy duy nhất cung cấp các lệnh quản trị chính:

  • ./start.sh serve thực hiện kiểm tra trước, đảm bảo image và weights đã có, khởi động TP2 và chờ sẵn sàng.
  • ./start.sh download tải xuống, xác minh và đồng bộ hóa weights mà không khởi chạy máy chủ.
  • ./start.sh stop xóa cả hai container và chấm dứt các tiến trình theo dõi nhật ký.
  • ./start.sh status báo cáo trạng thái container trên cả hai nút.
  • ./start.sh logs [N] hiển thị N dòng cuối từ nhật ký của nút đầu và worker.
  • ./start.sh smoke gửi một lượt hoàn tất greedy nhanh đến API đang chạy.
  • ./start.sh doctor chạy lại toàn bộ kiểm tra trước về môi trường và công thức triển khai.

Khi chẩn đoán sự cố khởi động, hãy kiểm tra .serve.log, .sglang.log và .sglang-worker.log. Tệp đầu tiên ghi lại đầu ra của bộ khởi chạy, còn hai tệp sau chứa nhật ký container của nút đầu và worker.

Hiểu Ngân sách Bộ nhớ GB10

Mỗi DGX Spark cung cấp một vùng bộ nhớ vật lý hợp nhất được dùng chung bởi các cấp phát CUDA, bộ nhớ máy chủ được ghim, Docker và hệ điều hành. Vì vậy, công thức sử dụng một phân số bộ nhớ tĩnh thận trọng thay vì xem bộ nhớ máy chủ và bộ nhớ GPU là các tài nguyên độc lập.

Bố cục được báo cáo trên mỗi nút bao gồm khoảng 62.5 GB cho weights chuyên gia NVFP4, weights dense, MTP và vision; khoảng 11 GB bộ nhớ máy chủ được ghim cho bảng PLE fp8; bộ nhớ đệm KV bf16 9 GB chứa khoảng 956,800 token; khoảng 3.6 GB cho trạng thái Mamba/GDN; và khoảng 8 GB cho CUDA graph cùng workspace NCCL hoặc cuBLAS.

Phân bổ có thể nhìn thấy qua CUDA kết quả là khoảng 95,6 GB, trong đó còn khoảng 17,5 GB khả dụng cho các tác vụ bổ sung. Bảng PLE được ghim không hiển thị dưới dạng phân bổ thiết bị theo từng tiến trình trong nvidia-smi, nhưng vẫn tiêu thụ cùng phần DRAM vật lý đó. Hãy theo dõi giá trị nhật ký available_gpu_mem của SGLang hoặc cột khả dụng từ free -h khi đánh giá dung lượng thực tế còn trống.

Giữ bật offload PLE

Không thêm --no-ple-offload-embedding trên GB10. Quy tắc tự động của SGLang giữ bảng embedding PLE được offload sang CPU. Ghi đè quy tắc này có thể đặt khoảng 26 GB bộ nhớ máy chủ được ghim cho mỗi rank ở phía GPU và khiến máy bị cấp phát quá mức.

Duy trì dung lượng dự phòng cho prefill tạm thời

Bộ lập chỉ mục QSA tạo một vùng làm việc logits fp32 có kích thước tăng theo chunk × history. Với kích thước chunk là 4096 và lịch sử 300.000 token, vùng tạm thời này có thể cần khoảng 8 đến 10 GB sau khi tính cả các bản sao gather và top-k liên quan.

Các giá trị được cung cấp cố ý mang tính thận trọng:

MEM_FRACTION_STATIC=0.82
CHUNKED_PREFILL_SIZE=1024
MAMBA_FULL_MEMORY_RATIO=0.3

Không tăng CHUNKED_PREFILL_SIZE quá 1024 cho ngữ cảnh 900.000 token nếu chưa lập hồ sơ mức bộ nhớ tạm thời đỉnh điểm so với ngân sách unified memory khả dụng. Kho lưu trữ cho biết kích thước chunk 4096 kết hợp với MEM_FRACTION_STATIC=0.85 đã đủ khiến các máy bị treo.

Tránh thử nghiệm với bộ cấp phát

Công thức triển khai khuyến cáo rõ ràng không đặt PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True. Cấu hình này chưa được kiểm chứng cho quá trình triển khai và không xuất hiện trong các công thức DGX Spark hoạt động tốt đã biết được tác giả sử dụng.

Điều chỉnh các tham số quan trọng

Đặt các tham số trong .env hoặc export chúng trong shell. Các giá trị trong shell sẽ được ưu tiên. Những thiết lập có khả năng cần điều chỉnh nhất là:

  • PORT: Mặc định là 8888 và liên kết API với mọi giao diện.
  • CONTEXT_LENGTH: Mặc định là 900000.
  • MAX_RUNNING_REQUESTS: Mặc định là 16, dù cấu hình Mamba giới hạn mức đồng thời thực tế ở 14 slot với tỷ lệ mặc định.
  • SPEC_STEPS, SPEC_TOPK và SPEC_DRAFT: Mặc định lần lượt là 3, 1 và 4 cho giải mã suy đoán NEXTN.
  • KERNEL_PATCH: Mặc định là 1 để image dự phòng SM121 được xây dựng và sử dụng.
  • IMAGE: Sử dụng trực tiếp image được chỉ định và bỏ qua bước vá.
  • CPUSET: Mặc định là 5-9,15-19 cho các lõi CPU lớn hơn của GB10. Đặt giá trị rỗng để tắt ghim CPU.
  • EXTRA_ARGS: Nối thêm các đối số SGLang ở cuối, cho phép ghi đè theo nguyên tắc giá trị xuất hiện sau cùng được ưu tiên.

Xử lý vòng lặp Thinking và Gọi công cụ

Một lỗi SGLang đã biết có thể ảnh hưởng đến các phiên kết hợp thinking mặc định với công cụ OpenAI và trình phân tích cú pháp gọi công cụ qwen3_coder. Máy chủ có thể liên tục phát token ID 0, được tokenizer này hiển thị là !, cho đến khi đạt max_tokens.

Cách khắc phục được ưu tiên là chỉ tắt thinking đối với các yêu cầu gửi kèm công cụ:

"chat_template_kwargs": {"enable_thinking": false}

Để tắt thinking trên toàn máy chủ khi sử dụng trình phân tích cú pháp công cụ, hãy dừng quá trình triển khai rồi khởi động lại với tùy chọn ghi đè:

./start.sh stop
EXTRA_ARGS='--tool-call-parser qwen3_coder --default-chat-template-kwargs {"enable_thinking":false}' ./start.sh serve

Nếu EXTRA_ARGS đã được cấu hình trong .env, hãy gộp các tùy chọn vào thiết lập hiện có đó. Không bật lại thinking trong cùng yêu cầu cung cấp công cụ. Không có trình phân tích cú pháp, thinking vẫn có thể hoạt động, nhưng các lệnh gọi công cụ sẽ xuất hiện dưới dạng XML <tool_call> trong nội dung thông thường thay vì message.tool_calls có cấu trúc. README cũng khuyến cáo giữ nhiệt độ của agent ở mức không quá 0.7 khi sử dụng cách khắc phục này.

Mẹo nâng cao về độ tin cậy và hiệu năng

Sử dụng giải mã suy đoán để tăng thông lượng

Giải mã suy đoán NEXTN là yếu tố chính thúc đẩy thông lượng trong thiết lập được đo. Với chuỗi mặc định 3/1/4, mỗi bước giải mã xác minh bốn token dự đoán trong một lượt forward. Cụm được thử nghiệm đạt đỉnh gần 117 token mỗi giây tổng hợp với hai luồng, sau đó chững lại khi nhiều luồng hơn tranh giành phần bộ nhớ còn lại.

Chọn tính tất định khi cần

Giải mã tham lam không tái lập theo từng bit trong cấu hình mặc định. Các token có xác suất gần bằng nhau đôi khi có thể thay đổi giữa các lần chạy, nhiều khả năng do sai khác trong phép rút gọn số thực của các GEMM MoE NVFP4 trên SM121. Để có hành vi chậm hơn nhưng tất định, hãy khởi động lại với:

EXTRA_ARGS="--moe-runner-backend triton" ./start.sh serve

Diễn giải đúng cảnh báo TileLang

Trong quá trình biên dịch JIT, TileLang có thể báo cáo rằng Logits(bx, position) được nhiều luồng ghi đồng thời. Kho lưu trữ xác định đây là cảnh báo sai vì các vị trí được tính toán là rời nhau, dù trình kiểm tra không thể chứng minh thuộc tính đó khi group là một giá trị runtime. Có thể tắt cảnh báo bằng PassKey.TL_DISABLE_DATA_RACE_CHECK nếu cần.

Bảo vệ quyền truy cập từ bên ngoài

API liên kết với 0.0.0.0, khiến API có thể được truy cập qua bất kỳ giao diện nào được cho phép. README mô tả việc truy cập từ các máy khách LAN hoặc Tailscale nhưng không thêm lớp xác thực. Hãy áp dụng các biện pháp kiểm soát phù hợp bằng tường lửa máy chủ, mạng riêng hoặc proxy khi endpoint không nên được truy cập công khai.

Kết luận

Kho lưu trữ này biến một triển khai hai nút phức tạp thành quy trình có thể lặp lại. Đóng góp chính của nó là sự kết hợp giữa phương án dự phòng Qwen Sparse Attention tương thích với SM121, các thiết lập bộ nhớ hợp nhất GB10 được giới hạn cẩn thận, tính song song tensor RoCEv2 trực tiếp và một tập lệnh vận hành duy nhất, có tính bất biến khi chạy nhiều lần.

Hãy bắt đầu với các giá trị mặc định được cung cấp, chạy ./start.sh doctor trước khi triển khai và tránh sử dụng trọng số giả, tắt chuyển tải PLE, các khối prefill quá lớn và các thiết lập bộ cấp phát thử nghiệm. Khi cụm đã sẵn sàng, các ứng dụng có thể sử dụng máy chủ cục bộ thông qua các giao diện chat và completion tương thích với OpenAI quen thuộc.