概览
本项目通过 OpenAI 兼容 API,使用一台 NVIDIA DGX Spark 提供 Qwen3.8 Flash Next 服务。项目使用 TensorFold v0.3.6.3、带有 MTP 草稿头的 MLX 4-bit 检查点,以及一组旨在加速提示词处理且不改变生成文本的补丁。
默认配置支持五个并发请求,每个请求都使用模型完整的 262,144 token 上下文窗口。项目还会在 CUDA 上加载模型自带的视觉塔,因此聊天消息可以包含图像和视频。
- API 模型 ID:
Qwen3.8-Flash-Next - 默认端点:
http://<spark-address>:8888/v1 - 并行流: 5
- 每个流的上下文: 262,144 tokens
- KV 池总量: 1,310,720 tokens
- KV 缓存: 默认为 int8
- 输入模式: 文本、图像和视频
主要功能
长上下文并发推理
TensorFold 为每个流分配独立的完整上下文缓存。在默认设置下,五个流各自获得一个 262,144 token 的提示词与回复窗口。生成的 int8 KV 池约占用 23.4 GiB。
OpenAI 兼容服务
服务器提供 /v1/models 和 /v1/chat/completions 等端点。OpenAI 兼容客户端只需修改基础 URL,并选择模型 ID Qwen3.8-Flash-Next 即可连接。
多模态提示词
用户消息可以包含 OpenAI 风格的 image_url 和 video_url 内容部分。支持的图像格式包括 JPEG、PNG 和 WebP。视频可以使用 MP4、WebM、MOV、MKV,或其他 FFmpeg 能够解码的格式。
经过补丁优化的提示词处理
随附的 TensorFold 补丁增加了 SSD 预读、原生多线程读取、改进的稀疏注意力块选择、可配置的提示词分块、复制草稿、实时 token 计数器以及 Flash Next 视觉支持。根据仓库中的测量结果,提示词处理速度约为对比的未打补丁版本的 1.7 倍,同时经过测试的文本回复保持字节级一致。
系统要求
克隆仓库前,请先准备主机:
- NVIDIA DGX Spark,或其他配备 128 GB 统一内存的 GB10 系统。
- 启动默认配置时约需要 115 GiB 可用内存。
- 支持 NVIDIA 容器运行时的 Docker。
- 属于
docker组的用户账户。 - 全新系统约需要 160 GB 可用磁盘空间。
- 可选:用于更快、可断点续传下载的 Hugging Face
hfCLI。 - 可选:位于
~/.cache/huggingface/token中的 Hugging Face token,或HF_TOKEN环境变量。
默认部署适用于基本处于空闲状态的 DGX Spark。在统一内存系统上,耗尽内存可能会导致机器冻结,而不是产生常规的分配错误。
安装与首次启动
1. 克隆仓库
git clone https://github.com/MiaAI-Lab/Qwen3.8-Flash-Next-Single-DGX-Spark-TensorFold.git
cd Qwen3.8-Flash-Next-Single-DGX-Spark-TensorFold2. 启动服务器
./start.sh首次启动会完成完整设置。脚本会在可用时拉取预构建容器镜像,下载约 106 GiB 的检查点,验证该检查点,并为 GB10 编译 CUDA 内核。预构建镜像约为 11 GB,而检查点在 Hugging Face 缓存中约占 114 GB。
启动期间,脚本会显示设置进度、服务器日志、权重加载进度和内存估算,随后运行冒烟测试。成功启动后,最后会显示一条消息,说明 Qwen3.8-Flash-Next 已在端口 8888 上运行。
根据 README,后续启动会跳过已完成的设置步骤,加载权重大约需要 2.5 分钟。
3. 在不启动服务的情况下完成准备
如果想提前下载并构建所有内容,请运行:
scripts/prepare.sh要从头重新构建容器镜像:
scripts/prepare.sh --rebuild准备脚本会检查 Docker、NVIDIA 运行时和磁盘空间。随后,它会获取或构建 TensorFold 镜像,将检查点下载到 Hugging Face 缓存,并使用 tensorfold info 验证模型。
基本 API 用法
检查可用模型
curl -s http://<spark-address>:8888/v1/models将 <spark-address> 替换为 DGX Spark 的主机名或 IP 地址。如果从 Spark 本机调用,可以使用 127.0.0.1。
发送聊天补全请求
curl -s http://<spark-address>:8888/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "Qwen3.8-Flash-Next",
"messages": [
{
"role": "user",
"content": "Write a Python fibonacci function."
}
],
"max_tokens": 1000
}'模型默认会在回答前进行思考,且推理过程会占用响应 token 配额。请将 max_tokens 设置得足够高,以同时容纳推理内容和最终答案。推理内容会返回在 reasoning_content 中,最终响应则出现在 content 中。
连接 OpenAI 兼容客户端
请使用以下值配置客户端:
- 基础 URL:
http://<spark-address>:8888/v1 - 模型:
Qwen3.8-Flash-Next
API 支持流式传输、类型化工具调用、推理内容、图像输入和视频输入。数组等工具参数会使用对应的 JSON 类型返回。
发送图像
默认情况下,媒体必须以数据 URL 的形式提供。以下 shell 示例会对 JPEG 进行编码,并要求模型描述它:
IMG=$(base64 -w0 photo.jpg)
curl -s http://<spark-address>:8888/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "Qwen3.8-Flash-Next",
"messages": [{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,'"$IMG"'"
}
},
{
"type": "text",
"text": "What is in this picture?"
}
]
}],
"max_tokens": 2000
}'单个请求最多可包含四张图像。每张图像最大为 10 MB,总大小上限为 20 MB。所有图像合计最多可使用 4,096 个 token。设置 "detail": "low" 可将单张图像限制为 256 个 token。
发送视频
视频使用 video_url 内容部分:
{
"type": "video_url",
"video_url": {
"url": "data:video/mp4;base64,..."
}
}单个请求最多可包含两个视频。单个视频最大为 64 MB,请求总大小上限为 96 MB,视频时长最多为一小时。默认情况下,服务器每秒采样两帧,整个视频最多采样 256 帧,并允许每个请求使用最多 16,384 个视频 token。
图像和视频提示不会保留用于前缀复用。启用视觉功能不会影响普通文本请求。
允许使用公开的 HTTPS 媒体 URL
默认使用数据 URL。若要让服务器获取公开的 HTTPS 图像和视频 URL,请使用以下命令重启:
VISION_URLS=1 ./start.sh restart只有在符合部署的安全要求和网络策略时,才应启用远程获取。
以纯文本模式运行
禁用视觉塔以仅提供文本服务:
VISION=0 ./start.sh restart纯文本模式不会加载 0.84 GiB 的视觉塔,并使用 4,096 行的提示分块,而启用视觉功能时默认使用 2,048 行。
管理服务器
日常操作请使用仓库提供的封装脚本:
./start.sh restart
./stop.sh
docker logs -f qwen38-flash-next-tf
curl -s http://<spark-address>:8888/health./start.sh restart会在替换正在运行的服务器前验证设置和参数。./stop.sh会停止容器并释放 GPU 内存。活动请求会被中断。docker logs -f会持续跟踪 TensorFold 服务器日志。/health会报告繁忙状态和实时 token 总数。
如果服务器已经在运行,直接执行 ./start.sh 不会对其进行任何操作。对于 systemd 等进程管理器,请使用前台模式:
FOREGROUND=1 ./start.sh配置上下文、并发和 KV 精度
默认值存储在 scripts/config.sh 中。可使用环境变量覆盖这些值,或在 start.sh 后传入 TensorFold 标志。
降低并发以获得更多余量
PARALLEL=4 ./start.sh restart四个 int8 流可提供 1,048,576 个 token 的 KV 池,报告的启动估算值约为 97.7 GiB。
使用更短的上下文窗口
./start.sh restart --context 131072额外的命令行参数会在默认参数之后传递给 tensorfold serve,因此具有更高优先级。运行 ./start.sh --help 可查看可用选项。
选择其他 KV 缓存类型
KV_DTYPE 接受 bf16、int8 或 int4:
PARALLEL=6 KV_DTYPE=int4 ./start.sh restartREADME 说明,int4 会使输出略有变化,但未提供质量测量结果。需要项目默认的平衡时,请使用 int8。当完整精度 KV 存储比流数量更重要时,请使用 bf16。
了解启动保护机制
TensorFold 会根据可用内存计算预算,并扣除相当于 RAM 十分之一的主机预留内存。如果请求的配置无法容纳,系统会在加载权重前拒绝启动,并在错误信息中指出一个应当能够容纳的上下文窗口。
控制思考和采样
思考模式的默认采样值为温度 1.0、top-p 0.95 和 top-k 20。请求可以覆盖 temperature、top_p、top_k 和 seed。温度设为 0 可启用贪心解码。
为单个请求禁用思考
{
"model": "Qwen3.8-Flash-Next",
"messages": [
{"role": "user", "content": "Answer in one sentence."}
],
"chat_template_kwargs": {
"enable_thinking": false
},
"max_tokens": 200
}设置推理强度
{
"chat_template_kwargs": {
"reasoning_effort": "low"
}
}该模板还接受 "xhigh"。如果省略推理强度,模板会使用中等强度作为默认值。顶层的 OpenAI 风格 reasoning_effort 字段会被忽略,因此请将其放在 chat_template_kwargs 中。
高级性能提示
将 n-gram 表保存在 SSD 上
默认的 PLE_ON_SSD=1 会将 29.8 GiB 的 n-gram 表保存在 SSD 上,而不是放入统一内存。这会为 KV 缓存保留更多内存。因此,默认配置需要快速的本地存储。
谨慎调整提示分块大小
启用视觉功能时,TENSORFOLD_PREFILL_ROWS默认为2048,以便为视觉塔预留空间。纯文本模式默认为4096。README指出,对于约3,000个令牌的提示词,4,096行可将提示词处理速度提高约2–5%,但需要额外约0.94 GiB内存。
TENSORFOLD_PREFILL_ROWS=4096 ./start.sh restart仅在有足够内存余量时增加此值。
控制 MTP 和复制草稿
默认的 MTP 配置每轮最多生成六个草稿,并在某个草稿的置信度低于60%时停止链式生成。复制草稿优化通过TENSORFOLD_MTP_COPY=1启用,并且至少需要两个并行流。它旨在改善引用或编辑较早提示词文本的回复。
请求串行参考解码
要绕过单个请求的草稿生成,并使用 TensorFold 一次一个令牌的参考路径,请添加:
{
"draft": false
}在将推测解码与串行参考进行比较时,这一选项很有用。
强制执行或跳过准备
PREPARE=1 ./start.sh restart
PREPARE=0 ./start.sh restart
PULL=0 scripts/prepare.shPREPARE=1会在重启前强制执行准备检查。PREPARE=0会跳过准备步骤。PULL=0会在本地构建镜像,而不是尝试使用预构建的镜像仓库镜像。
修改patches/中的文件后,请重新构建镜像,以便将这些补丁写入 TensorFold。
验证与基准测试
该仓库包含用于调用运行中服务器的工具。其 API URL 默认为http://127.0.0.1:8888。
tools/bench.py local-test
tools/needle.py
tools/toolcheck.py
tools/visioncheck.pytools/bench.py会测量多种提示词大小,并执行简短的解码检查。tools/needle.py会在约195,000个令牌的提示词中隐藏一段口令,并验证其检索结果。tools/toolcheck.py会检查数组类型的工具参数是否以 JSON 数组形式返回。tools/visioncheck.py会发送一张包含红色圆形和蓝色方形的生成图像,然后检查两者是否都能被识别。
要从另一台机器进行测试,请设置API_URL:
API_URL=http://<spark-address>:8888 tools/bench.py remote-test预期性能
该仓库报告了以下解码结果,测试环境为一台启用 int8 KV 缓存、由 SSD 支持的 n-gram 表和 MTP 草稿生成的 DGX Spark:
- 一个请求:每秒62.4个令牌,首个令牌耗时152毫秒。
- 两个请求:聚合速度为每秒90.5个令牌。
- 四个请求:聚合速度为每秒106.7个令牌。
- 五个请求:聚合速度为每秒119.3个令牌,即每个请求每秒27.0个令牌。
报告的预填充速度范围为:对于包含8,229个令牌的提示词,约每秒2,503个令牌;对于包含131,110个令牌的提示词,每秒2,200个令牌。这些数据是项目测量结果,并非性能保证,实际表现可能因配置、提示词结构、媒体输入、存储和可用内存而异。
结论
该仓库整合了在一台 DGX Spark 上运行 Qwen3.8 Flash Next 所需的模型、TensorFold 运行时、CUDA 专用设置、性能补丁和运维脚本。建议从默认的 int8、五流配置开始,通过兼容 OpenAI 的 API 验证服务,然后根据工作负载和内存余量调整并发数、上下文大小、视觉功能和 KV 精度。
