文本与 LLM 模型

每种文本架构的下载与运行命令,随后按家族说明图像、音频与 PDF 输入、思考模式以及工具调用能力。

嵌入模型: Snowflake Arctic Embed L v2.0、MiniLM,以及支持文本与可选图像/音频/视频输入的 EmbeddingGemma 2。通过 --embeddings 提供兼容 OpenAI/Ollama 的向量 API;后端支持依模型而定。模型、API 与验证范围 →

下载并运行

运行构建命令前,请先按平台安装并验证 .NET 10 SDK。第一个代码块是已验证的 Gemma 4 E4B 快速上手。所有代码块都使用 Hugging Face CLI(pip install -U huggingface_hub);其后的各家族代码块假定已完成完整源码构建。从仓库根目录运行。CLI 的一次性文本提示从 --input 指定的文件读取(先把问题写入 prompt.txt——--prompt 只用于图像与视频生成模型)。按硬件把 --backend 换成 ggml_metal、ggml_vulkan 或 ggml_cpu(CLI 默认后端为 ggml_cpu)。

快速上手:Gemma 4 E4B Q8_0(原生 GGML)

请为 7.48 GiB 模型下载与首次 restore/构建预留时间,耗时取决于网络与机器。本示例使用 E4B Q8_0 家族;链接的公开 ggml-org 仓库是推荐下载源。下面的代码块面向 Linux + NVIDIA:

hf download ggml-org/gemma-4-E4B-it-GGUF gemma-4-E4B-it-Q8_0.gguf --local-dir models
TENSORSHARP_GGML_NATIVE_ENABLE_CUDA=ON dotnet build TensorSharp.slnx -c Release -p:TensorSharpSkipMlxNative=true
echo "请说明本地推理的价值。" > prompt.txt

# 纯文本不需要 mmproj。
dotnet run --project TensorSharp.Cli -c Release --no-build -- --model models/gemma-4-E4B-it-Q8_0.gguf \
    --input prompt.txt --max-tokens 300 --backend ggml_cuda
dotnet run --project TensorSharp.Server.Host -c Release --no-build -- --model models/gemma-4-E4B-it-Q8_0.gguf \
    --backend ggml_cuda

Apple Silicon 请省略 CUDA 环境变量并使用 ggml_metal;受支持的 Windows/Linux Vulkan GPU 请改为请求 TENSORSHARP_GGML_NATIVE_ENABLE_VULKAN=ON 并使用 ggml_vulkan。图像、视频或音频输入还需运行 hf download ggml-org/gemma-4-E4B-it-GGUF mmproj-gemma-4-E4B-it-Q8_0.gguf --local-dir models,并传入 --mmproj models/mmproj-gemma-4-E4B-it-Q8_0.gguf。服务端浏览器界面位于 http://localhost:5000/,存活检查为 /health。Windows PowerShell 与完整平台语法见快速开始。

DeepSeek V4.1 Flash 1017(文本、图像/视频、思考、工具)

DeepSeek V4.1 有独立的计算图,包含压缩注意力、索引器、超连接与内嵌 Engram 特征,并不是把 V4 权重改名。最新选取的转换为 unsloth/DeepSeek-V4.1-Flash-1017-GGUF,UD-IQ2_XXS、六个分片,Hugging Face 修订 60ad3651。准确文件名、转换资格、启动设置与后端局限见当前模型卡,不要套用旧检查点的数字。

ggml_cuda 是服务后端;--tp N 与 --layer-split N 是不同的本地放置模式,吞吐取决于检查点与互连。托管 cpu 执行器属于正确性与可移植性路径,其 PyTorch 参照门槛覆盖小型合成模型,不构成完整检查点的 CPU 质量资格。图像与视频需要匹配的视觉伴随模型;音频会被拒绝。

2026-10-22–23 在五张 A40 上的记录:约 1.8K token 提示下,TP5 精确 prefill 为 563.9 tok/s,对照 llama.cpp 按层切分 174.6(3.23×);默认近似 YOCO 路径为 960.5(5.50×)。上下文 32,768、并发 1、输出 256 token、贪心采样并关闭思考,预热后三次取中位数。这是内部 prefill 计时,不是客户端 TTFT。近似执行存在实测质量代价:困惑度为近似 2.4978、精确 2.4811、llama.cpp 2.4697。两种提示长度、精确/近似结果与局限 →

DeepSeek V4 Flash(284B MoE,文本、思考、工具、DSpark)

一个 284B 的专家混合模型,配备 128 token 的原始滑动窗口加块压缩注意力(官方宣称 1M 上下文)。它不走通用的逐算子前向:TensorSharp 通过三套专属的整模型执行器之一运行它 —— --backend cuda(Direct CUDA,不依赖 ggml)、--backend ggml_cuda / ggml_vulkan(原生 ggml),以及 --backend cpu(100% 纯 C#,零原生依赖)。GPU 执行器通过 --layer-split N 将整层放到 N 张本地 GPU,让大于单卡显存的模型也能运行。未配置放置方式时默认单设备;CPU 执行器从映射分片流式读取权重。

# Q8 档位约需 160 GB 权重 —— 显存不足时改用更小的量化子目录
hf download unsloth/DeepSeek-V4-Flash-0731-GGUF --include "UD-Q8_K_XL/*" --local-dir models
hf download bleysg/DeepSeek-V4-Flash-DSpark-drafter-GGUF DSpark-drafter-Q2K-Q8-0731.gguf --local-dir models

# 普通 decode —— --model 指向第一个分片
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q8_K_XL/DeepSeek-V4-Flash-0731-UD-Q8_K_XL-00001-of-00005.gguf \
    --backend ggml_cuda --layer-split 4 --input prompt.txt --max-tokens 200

# DSpark 块级投机解码(decode 约 1.3-1.4×,以贪心采样实测)
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q8_K_XL/DeepSeek-V4-Flash-0731-UD-Q8_K_XL-00001-of-00005.gguf \
    --backend ggml_cuda --layer-split 4 --draft-model models/DSpark-drafter-Q2K-Q8-0731.gguf \
    --input prompt.txt --max-tokens 200 --temperature 0

# 通过 HTTP 服务,4 张 GPU,开启投机
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/UD-Q8_K_XL/DeepSeek-V4-Flash-0731-UD-Q8_K_XL-00001-of-00005.gguf \
    --backend ggml_cuda --layer-split 4 --draft-model models/DSpark-drafter-Q2K-Q8-0731.gguf

DSpark 每步起草一整块 token,主干用一次批量前向验证整块,因此贪心输出保持不变。无论在 CLI 还是服务端,每一行验证都用本次运行或该请求自己的采样器抽取,因此可与任意采样设置组合;使用重复 / 存在 / 频率惩罚时接受率会下降,因为起草的整块不经过惩罚。详见 DSpark 投机解码。

GLM 5.x(744B-A40B MoE,文本、思考、工具)

一个 744B 的混合专家模型——256 个路由专家 top-8 加一个共享专家——建立在 DeepSeek 稀疏注意力之上:带权重吸收的多头潜在注意力(MLA),使得缓存每 token 每层只占一行 576 宽的数据,再加上一个"lightning indexer"决定每个 query 可以看到哪些历史 token(自报 1M 上下文)。与 DeepSeek V4 一样,它不走通用的逐算子前向:--backend ggml_cuda / ggml_vulkan / ggml_cpu / ggml_metal 走原生整模型 ggml 执行器,在 CUDA 或 Vulkan 上通过 --layer-split N 将 226 GiB 权重按层放到 N 张本地 GPU(默认单设备);而 --backend cpu(100% 纯 C#、无原生依赖)与 --backend cuda 走托管逐算子路径。MLX 跑不了它。多分片 GGUF 由 GgufFile 自己读取,所以 --model 指向第一片即可。下面的命令面向 GLM-5.2;GLM-5.3(非 Flash)共用同一条 glm-dsa 加载路径,其配方在其后单独给出。

# UD-IQ2_XXS 这一档约 226 GiB(6 个分片)——想要更大或更小可换一个量化目录
hf download unsloth/GLM-5.2-GGUF --include "UD-IQ2_XXS/*" --local-dir models

# 在 3×96 GB GPU 上显式按层切分 —— --model 指向第一个分片
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-IQ2_XXS/GLM-5.2-UD-IQ2_XXS-00001-of-00006.gguf \
    --backend ggml_cuda --layer-split 3 --input prompt.txt --max-tokens 200

# 交互式 + 思考模式
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-IQ2_XXS/GLM-5.2-UD-IQ2_XXS-00001-of-00006.gguf \
    --backend ggml_cuda --layer-split 3 --interactive --think

# 显存不够?把前 N 层的路由专家留在系统内存里
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-IQ2_XXS/GLM-5.2-UD-IQ2_XXS-00001-of-00006.gguf \
    --backend ggml_cuda --layer-split 3 --n-cpu-moe 30 --input prompt.txt --max-tokens 200

# 以 HTTP 服务方式运行
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/UD-IQ2_XXS/GLM-5.2-UD-IQ2_XXS-00001-of-00006.gguf \
    --backend ggml_cuda --layer-split 3

自报的 1M 上下文是上限而非承诺:1M token 的 MLA 缓存约 93 GiB,所以权重落盘之后加载器会去问各设备实际还剩多少显存,按「缓存加一整个 prefill 计算图」能装下的大小定上下文,并把选中的值打印出来。在 3× RTX PRO 6000 上用 GLM-5.2 实测,按层切分是 342,272 token,--n-cpu-moe 30 是 646,400,--tp 3 是 91,136(每个 rank 都要各自持有一份全长缓存)。想把某个长度变成硬性要求,就设 MAX_CONTEXT——放得下就照办,放不下会带着数字直接报错。

--tp N 这里也能用,但在 PCIe 互连的卡上它是容量特性而非速度特性:78 层里每层都要两次 all-reduce,占用的总线时间比拆分省下的算力还多,所以在 GLM-5.2 上 --tp 3 实测 pp2048 505.6 / tg64 17.6 tok/s,而按层切分是 915.9 / 43.9。并发靠原生的按序列槽位承载(每个请求拥有自己的 MLA 与索引器缓存),默认启用的批处理融合解码在 4 路并发下带来 1.81 倍总吞吐(在 GLM-5.2 上实测);设置 TS_BATCHED_FUSED_DECODE=0 可关闭。参见张量并行与连续批处理。

GLM-5.3(非 Flash)与 GLM-5.2 的 glm-dsa 块结构完全相同——79 个块(78 个主干块加一个 NextN 块)、256 个路由专家 top-8 外加一个共享专家、带 lightning indexer 的 MLA、rope base 8e6——所以它直接在 GLM-5.2 这条路径上加载,不需要新代码,也不需要新开关:同一个架构描述符同时服务 GLM-5.2、GLM-5.3 与 GLM-5.3-Flash,是不是 Flash 只由 general.architecture 上的一个布尔值决定。unsloth/GLM-5.3-GGUF 每种量化一个子目录,均为多分片——UD-Q2_K_XL 是 7 个分片、236.4 GiB。它仅文本,而且是双重意义上的仅文本:该仓库在任何量化下都没有发布 mmproj;就算给 glm-dsa 传了 --mmproj,也只会告警并忽略而不会报错,拿到的是一次纯文本运行而不是一次失败。--spec 会把 blk.78 上那个完整的 NextN 块加载进来,但该块没有自己的 nextn.shared_head_head.weight,只能借用主干的 LM head,而这颗 head 在 --tp 下是按列切分的——因此推测解码只在单设备或显式 --layer-split N 放置模式(不启用张量并行)时生效,而且这个开关必须在模型加载前就出现在命令行上。

# UD-Q2_K_XL 这一档约 236.4 GiB(7 个分片)——想要更大或更小可换一个量化目录
hf download unsloth/GLM-5.3-GGUF --include "UD-Q2_K_XL/*" --local-dir models

# 在 8×46 GB GPU 上显式按层切分 —— --model 指向第一个分片
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-UD-Q2_K_XL-00001-of-00007.gguf \
    --backend ggml_cuda --layer-split 8 --input prompt.txt --max-tokens 200

# NextN 推测解码 —— 此处显式使用按层切分,不启用张量并行
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-UD-Q2_K_XL-00001-of-00007.gguf \
    --backend ggml_cuda --layer-split 8 --spec

实测:8× A40 46 GB(无 NVLink)、GLM-5.3 UD-Q2_K_XL、10,531 token 提示、输出 300 token、3 次取中位数、整层放置:prefill 251.6 t/s、decode 20.48 t/s、加载 264 秒;同一台机器上 llama.cpp 是 decode 20.28 t/s、加载 753 秒——decode 打平,而加载这份 236.4 GiB 的检查点快 2.9 倍。真正的差距在首 token 时延:41.9 秒对 29.0 秒,约慢 1.4 倍(那一格 llama.cpp 没有记录 prompt token 数,因此不给出它的 prefill tok/s)。--tp N 在这里可以传,但只支持本地单进程,而且从未在 GLM-5.3 上跑过:每个 rank 都要持有一份完整复制的 KV 缓存,唯一有记录的算术是一次装不下——--tp 8 每个 rank 需要 41.7 GiB,而卡只有 46 GB。--tp-node-id / --tp-peers 则对整个 GLM 家族在建模型之前就直接拒绝。两个版本共用同一份GLM 模型卡。

GLM-5.3-Flash(320B MoE,文本 + 图像、思考、工具)

这个混合架构的后继型号走的是与 GLM-5.2 完全相同的原生整模型 ggml 执行器和同一个模型类——GGUF 架构 id 是 glm5next——只是在其上叠了四处架构改动。320B 参数,288 个路由专家 top-8 外加一个共享专家,46 个块 = 45 个主干块 + 1 个 NextN 块。45 个主干层里有 34 层是 KDA 线性注意力;另外 11 层是 NoPE MLA + DSA(文本塔里任何地方都没有 rope,512 宽的潜变量本身就是缓存行);索引器是池化的——4 格一池,top-k 2048 在池上取,再展开到池内成员;超连接是 ×4 流的 Sinkhorn 版本;所有 SwiGLU 都按上限 10 做钳位。KDA 的递归状态无法回退,因此只有当新提示恰好是缓存前缀的延长时才会复用该前缀。

# UD-Q2_K_XL 这一档约 101 GiB——想要更大或更小可换一个量化目录
hf download unsloth/GLM-5.3-Flash-GGUF --include "UD-Q2_K_XL/*" --local-dir models
hf download unsloth/GLM-5.3-Flash-GGUF mmproj-BF16.gguf --local-dir models

# 在 2×96 GB GPU 上显式按层切分 —— --model 指向第一个分片
# (N 取决于你下载的那个量化目录里有多少个分片)
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-Flash-UD-Q2_K_XL-00001-of-0000N.gguf \
    --backend ggml_cuda --layer-split 2 --input prompt.txt --max-tokens 200

# 图像理解 —— GLM-OCR ViT 以 mmproj-BF16.gguf 形式发布
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-Flash-UD-Q2_K_XL-00001-of-0000N.gguf \
    --mmproj models/mmproj-BF16.gguf --image photo.png --input question.txt \
    --max-tokens 300 --backend ggml_cuda --layer-split 2

# 显存不够?把前 N 层的路由专家留在系统内存里
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-Flash-UD-Q2_K_XL-00001-of-0000N.gguf \
    --backend ggml_cuda --layer-split 2 --n-cpu-moe 10 --input prompt.txt --max-tokens 200

# 以 HTTP 服务方式运行
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/UD-Q2_K_XL/GLM-5.3-Flash-UD-Q2_K_XL-00001-of-0000N.gguf \
    --mmproj models/mmproj-BF16.gguf --backend ggml_cuda --layer-split 2

目前能跑的:用 --layer-split N 将整层放到 N 张本地 GPU、--cpu-moe / --n-cpu-moe N 把专家放在主机内存、以服务形式运行时的原生按序列槽位,以及视觉——--image、多图提示与多轮图像会话,都走 GLM-OCR ViT。在 GGML GPU 后端上,传入 --tp N 与 GLM-5.2 一样选择仅支持本地单进程的原生张量并行:KDA / MLA head 与路由专家隐藏行切分,KDA 递归状态按 rank 持有。完整切分、每张本地 GPU 一个 rank、不启用 CPU MoE 或 tracing、且具备原生超连接内核时,按 rank 分段计算图会并发提交:路由 MoE 局部输出先归约,随后每个 rank 在本地计算并加入其复制的共享专家,再进入 Sinkhorn 超连接;超连接、池化 indexer、router、norm、稠密层与 embedding 保持不切分并按 rank 执行,output norm / LM head 留在 rank 0。CPU MoE、tracing、部分切分、超额 rank 或缺少原生超连接内核时选择组合调度器回退,其中共享专家只在 rank 0 运行一次。GLM-5.2 与 GLM-5.3-Flash 的原生 TP 路径都只支持本地单进程,不支持分布式或跨节点。暂不支持:NextN/MTP 推测解码。

实测:2× RTX PRO 6000 Blackwell(96 GB)、GLM-5.3-Flash-UD-Q2_K_XL(101 GiB)、按层切分、两个引擎都用 n_ubatch 2048、背靠背运行:pp2048 llama.cpp 2070 t/s 对 TensorSharp 2014,pp16384 1690 对 1692,pp32768 1483 对 1446,tg64 36.6 对 73.5。prefill 双方相差不过几个百分点;decode 是 llama.cpp 的 2.0×。

它现在也能在 --backend cpu(100% 纯 C#、无原生依赖)上跑:glm5next 的 NoPE MLA(文本塔里没有 rope 半边,也就没有可切分的部分)以及它使用的 IQ2_XS / IQ4_XS 权重都已获得托管支持。但在这条路径上它明显落后于 GGML 后端:在 122 CPU 的机器上(22 token 提示、输出 16 token)实测 prefill 3.1 / decode 1.6 tok/s,而同文件同机器上的 ggml_cpu 是 17.7 / 3.9——prefill 约慢 5.7 倍,decode 约慢 2.4 倍,其中约 89% 的时间花在 MoE 专家路径上。请把它当作用于 A/B 的参考实现,而不是逐位对齐的实现:与 ggml_cpu 相比,prefill 的 logits 在 154880 词表上余弦相似度为 0.9567,贪心解码出的文本也不同——原生一侧排前两位的 logit 只差 0.11,而托管路径把两者的顺序调了个个儿。这与 2 bit 下专家选择的敏感性相符,但并不构成证明:0.96 低于更高精度 checkpoint 应有的 ~0.999,而当时没有更高精度的 GLM-5.3-Flash GGUF 可作对照。完整的实测数据、为此所做的四处修复与这一说明,见 GLM 模型卡。

Qwen 3.5 / 3.6(文本 + 图像、思维链、工具;3.6 支持 NextN MTP)

hf download unsloth/Qwen3.5-9B-GGUF Qwen3.5-9B-UD-Q4_K_XL.gguf --local-dir models
hf download unsloth/Qwen3.5-9B-GGUF mmproj-F16.gguf --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/Qwen3.5-9B-UD-Q4_K_XL.gguf --mmproj models/mmproj-F16.gguf \
    --image photo.png --max-tokens 300 --backend ggml_cuda
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/Qwen3.5-9B-UD-Q4_K_XL.gguf --mmproj models/mmproj-F16.gguf --backend ggml_cuda

Qwen 3.6 NextN 必须从保留该块的 -MTP- 仓库下载,并在 CLI 或服务端加入 --spec —— 该草稿头内嵌在主干 checkpoint 里,加载它要把额外权重调入显存,因此需要显式开启;基础仓库 GGUF 会剥离 NextN 块并回退到标准解码:

hf download unsloth/Qwen3.6-35B-A3B-MTP-GGUF Qwen3.6-35B-A3B-UD-Q4_K_M.gguf --local-dir models

dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/Qwen3.6-35B-A3B-UD-Q4_K_M.gguf --backend ggml_cuda --spec

Qwen3.8-27B 是稠密模型,走同一个 qwen35 插件——例如 unsloth/Qwen3.8-27B-GGUF 的 Qwen3.8-27B-UD-Q4_K_XL.gguf,config/agent-qwen3.8-27b.json 按提交与 SHA-256 钉住该文件,它保留内嵌的 NextN 块,可用于 --spec。它还可以通过 --draft-model 挂上 DFlash2 块草稿模型(独立 GGUF:z-lab/Qwen3.8-27B-DFlash2-GGUF),挂上后它会取代 NextN 块。收益几乎完全取决于负载:在 RTX 3080 Laptop、UD-IQ3_XXS 上,自由散文快 1.14×,高度可预测的提示快 1.63×——详见 Qwen 3.5 卡片第 12.4 节。

Qwen 3.8 Flash Next(混合 MoE,文本 + 图像/视频、思考、工具、MTP 头)

一个混合专家模型,GGUF 架构 id 为 qwen4exp:GatedDeltaNet 递归层与全注意力层交错(其中一部分还挂在 Qwen 稀疏注意力的索引器之后),一个 PLE n-gram 嵌入块,×4 的超连接流,以及 512 专家的 MoE。48 层,隐藏维度 2560,24 个 query 头 / 2 个 KV 头、head_dim 256,词表 248,320,每个 token 从 512 个专家里用 10 个,48 层中有 36 层带 GDN,PLE 在第 1 层。在各 ggml 后端上,整个 token(几乎)作为一张图跑完——嵌入、图内 PLE、全部 48 层、最后的混合器与 LM 头——并从按形状索引的已捕获图缓存中回放。视觉走 Qwen3.5-VL 塔,使用 (T,H,W) IMRoPE 位置,因此多图提示与多轮图像会话都可用。只有新提示恰好是缓存前缀的延长时才会复用该前缀(GDN 递归无法回退),而在基数树前缀缓存中,这种复用止于对话中第一个图像或视频片段:之后的轮次最多只能恢复一个结束于该附件之前的检查点(通常是系统提示词),其余部分重新 prefill。并发请求由按序列的状态持有者承载——每个请求拥有自己的注意力 KV 与索引器缓存、自己的 GDN 与 PLE 状态——因此请求之间的切换只是换一个引用。思考可以开关,与 Qwen 3.5 相同:--think / "think": true 会打开 <think> 块,不开启时发布的模板会渲染一个已闭合的空块。

🧰

工具状态:qwen4exp 通过 Qwen 3.5 解析器返回结构化工具调用——<tool_call> 块内可以是 XML 形式的 <function=…><parameter=…>,也可以是 JSON,流式输出与开启思考时同样适用——因此客户端工具、内置 Agent Skills 与代码执行工具,以及服务端的子智能体委派都会提供给它。2026-09-19 在三张 A40、UD-IQ4_XS 上验证:12 个通用工具调用用例全部通过,且每个都完成了一次工具结果往返;技能 / shell / 代码工作流的结果与仍失败的用例见模型卡。

# UD-Q2_K_XL 这一档约 73.4 GiB——想要更大或更小可换一个量化目录
hf download unsloth/Qwen3.8-Flash-Next-GGUF --include "UD-Q2_K_XL/*" --local-dir models
hf download unsloth/Qwen3.8-Flash-Next-GGUF mmproj-BF16.gguf --local-dir models

# 纯文本 —— --model 指向第一个分片
# (N 取决于你下载的那个量化目录里有多少个分片)
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/Qwen3.8-Flash-Next-UD-Q2_K_XL-00001-of-0000N.gguf \
    --backend ggml_cuda --input prompt.txt --max-tokens 300

# 图像理解
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/UD-Q2_K_XL/Qwen3.8-Flash-Next-UD-Q2_K_XL-00001-of-0000N.gguf \
    --mmproj models/mmproj-BF16.gguf --image photo.png --input question.txt \
    --max-tokens 300 --backend ggml_cuda

# 两张 GPU:这里的 --layer-split N 走的是按层切分,不是张量并行
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/UD-Q2_K_XL/Qwen3.8-Flash-Next-UD-Q2_K_XL-00001-of-0000N.gguf \
    --mmproj models/mmproj-BF16.gguf --backend ggml_cuda --layer-split 2

现在支持本地 CUDA 张量并行。ggml_cuda 上的 --tp N 切分路由/共享 FFN 的中间通道和输出行,使用 FP32 gather 保持 down projection 的归约顺序;注意力、GDN、QSA 与 PLE 的权重/状态保持复制。大批量加载之前检查并行度、量化和精确条带内核布局。真机覆盖为 NVIDIA A40 上 UD-IQ4_XS 的 TP2/TP4;UD-Q2_K_XL 的 IQ2_XS/IQ3_XXS FFN 与浮点 FFN 会被 TP 拒绝。此模式仍禁用前缀检查点。--layer-split N 仍是独立的 GGML CUDA/Vulkan 选项,包括 UD-Q2_K_XL;Direct cuda 引擎使用按层切分。两种模式不可组合,且不支持多节点组。旧的 2× A100、UD-Q2_K_XL 实测属于按层切分:贪心输出相同,显存 24.2 + 26.2 GB,约 1520–1550 prefill / 56 decode tok/s,不是新 TP 路径的测量。量化限制、数值对齐与计时范围 →

投机解码使用独立的共享 MTP 头,而不是主干里的张量(已发布的 Q8_0 分片完全不含 nextn/mtp 张量):在 GGML 后端上用 --draft-model mtp-Qwen3.8-Flash-Next-shared-Q8_0.gguf(2,786,568,256 字节;取自 unsloth/Qwen3.8-Flash-Next-GGUF 的修订版本 38bb39ee)挂上它。它只为从位置 0 开始 prefill 的单独请求起草;延续保留持有者或共享前缀克隆的轮次按普通方式解码。在 UD-Q2_K_XL、三张 A40 按层切分、--spec-draft 3 下实测:192 token 的代码复制流与普通贪心逐字相同,在当前的验证行内核下(每个验证行都与其 decode 步逐位相同)为普通 decode 的 1.69×(83.2 对 49.1 tok/s;2026-09-17 改为逐位一致之前为 1.75–1.96×);但散文并不划算——512 token 的回答解码为 44–46 tok/s,普通解码为 52。详见模型卡。

超出内存运行。UD-Q2_K_XL 有 78.9 GB(73.4 GiB),但每个 token 只读取其中 28.8 GB n-gram 表的 16 行,以及每层 512 个专家中的 10 个,因此 TensorSharp 能在装不下它的机器上运行它。在 ggml_metal 上,n-gram 表留在 GGUF 内存映射中,每个 token 的行按需读取;未指定 --n-cpu-moe N 或 --cpu-moe 时,引擎还会自行规划专家卸载:在放得下的前提下把整层专家留在 GPU 上,最前面若干层的专家则在主机上直接从同一映射计算——热的专家留在页缓存中,其余在 token 需要时从 SSD 读取。在 48 GB 的 M5 Pro 上(48 层中有 33 层的专家在主机上),1,818 token 的提示、贪心生成 256 个 token 实测 prefill 109.4–115.5 / decode 12.8–12.9 tok/s;同一台 Mac 上 llama.cpp 用 -ngl 0 -t 12 为 20.4–22.4 / 13.00–13.24(加 --no-op-offload 为 28.8–31.6 / 11.94–12.48),它的完整 GPU 卸载在这台机器上内存不足。--backend mlx 会被直接拒绝:MLX 没有稀疏注意力索引器、超连接、n-gram 表以及 IQ2_XS/IQ3_XXS 专家的内核。Direct CUDA 引擎(cuda)能运行这些专家:在 2× A40、--layer-split 2、预热后,同一提示实测 1,612–1,613 / 56.85–56.93 tok/s(ggml_cuda 为 1,174–1,217 / 52.9–53.1),llama.cpp 为 752–963 / 59.04–59.86。TensorAgent 在 48 GB 的 Mac 上提供这个文件;详见模型卡。

Bonsai2 27B(PRISM 三值 Qwen 3.5,文本 + 图像)

Ternary-Bonsai-2-27B-PQ2_0.gguf 与 -PTQ1_0.gguf 声明 general.architecture = qwen35——64 层,其中 48 层 GatedDeltaNet、16 层全注意力——并另外带有 PRISM 带符号 Hadamard 元数据(prism.hadamard.*)以及发布方自定义的张量类型 PQ2_0(142)与 PTQ1_0(143)。TensorSharp 依据这些元数据识别它们,在加载时把权重无损转码为 GGML Q2_0(PQ2_0 约大 6%,PTQ1_0 约大 29%,因此加载后的内存并不等于文件大小),并对投影输入与 embedding 输出施加声明的旋转;不施加这些变换读出的是一个错误的网络。它需要单设备 GGML 后端:cpu、cuda、mlx 与 --tp 都会被拒绝,而不是悄悄跳过旋转。配套投影器 Ternary-Bonsai-2-27B-mmproj-BF16.gguf / -mmproj-Q8_0.gguf 提供图像输入——CLI 会在模型旁边查找,服务端只通过 --mmproj 加载。Bonsai2 卡片列出了这些文件的确切字节数与 SHA-256。它们发布在 prism-ml/Ternary-Bonsai-2-27B-gguf(Apache-2.0;钉住的修订版本为 b072e1d),TensorAgent 在 16 GB 设备上把 PTQ1_0 文件(连同可选的 Q8_0 投影器)作为实验性下载提供。

# 显式限制上下文,而不是按宣称的 262k 窗口分配
MAX_CONTEXT=4096 KV_CACHE_DTYPE=f16 \
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model /path/to/Ternary-Bonsai-2-27B-PQ2_0.gguf \
    --backend ggml_metal --input prompt.txt --max-tokens 128 --temperature 0

# 以服务形式运行,并加载投影器以支持图像输入
MAX_CONTEXT=4096 KV_CACHE_DTYPE=f16 \
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model /path/to/Ternary-Bonsai-2-27B-PTQ1_0.gguf \
    --mmproj /path/to/Ternary-Bonsai-2-27B-mmproj-Q8_0.gguf --backend ggml_metal

仅在 Metal(M5 Pro)上验证过(2026-09-22):两种格式在 4 个 32 token 的提示上都逐字复现了发布方 llama.cpp 分支的贪心输出,并通过了 HTTP、JSON、工具调用与图像冒烟测试(属功能性检查,不是质量评估)。与该分支相比,PQ2_0 的 prefill / decode 为 364.05 / 25.50 tok/s,对方为 384.44 / 26.96;PTQ1_0 为 364.49 / 25.53,对方为 357.67 / 26.31——卡片记录的性能目标尚未达成。之后修复了一个仅在 CUDA 上出现的带符号 Hadamard 路径缺陷,但没有提交任何 CUDA 结果:CUDA、Vulkan、iOS 与张量并行执行都尚未验证。

GPT OSS(文本、始终思考、工具)

hf download ggml-org/gpt-oss-20b-GGUF gpt-oss-20b-MXFP4.gguf --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/gpt-oss-20b-MXFP4.gguf --input prompt.txt --max-tokens 400 --backend ggml_cuda
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/gpt-oss-20b-MXFP4.gguf --backend ggml_cuda

Nemotron-H(文本;Omni 分发支持图像)

hf download bartowski/nvidia_Nemotron-H-8B-Reasoning-128K-GGUF nvidia_Nemotron-H-8B-Reasoning-128K-Q4_K_M.gguf --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/nvidia_Nemotron-H-8B-Reasoning-128K-Q4_K_M.gguf --input prompt.txt \
    --think --max-tokens 400 --backend ggml_cuda
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/nvidia_Nemotron-H-8B-Reasoning-128K-Q4_K_M.gguf --backend ggml_cuda

图像输入请改用上表 Nemotron 3 Nano Omni GGUF 与 mmproj-BF16.gguf。音频需要 Parakeet/FastConformer 音频塔,而任何公开 GGUF 都不带它:TensorSharp 可从另行准备的伴随 GGUF 运行它(转换脚本在 eng/nemotron-audio/),通过 --mmproj 传入,或与视觉投影器并用时通过 TS_NEMOTRON_AUDIO_MMPROJ 指定。没有它时音频会被拒绝(服务端返回 HTTP 400,CLI 报错),而不是被悄悄丢掉。在 CPU 上,该音频塔以 F32 计算(prepare_f32.py 生成的伴随文件)时与参考模块一致;在训练好的权重上,prepare.py 生成的 BF16 计算伴随文件仍未通过该比对。语音问答质量与 GPU 执行尚未验证。

Nemotron 3.5 Lightning 30B-A3B 走同一条 nemotron_h_moe 路径——23 层 Mamba-2 + 23 层 MoE + 6 层注意力,例如 unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF 中的 NVIDIA-Nemotron-3.5-Lightning-30B-A3B-MXFP4_MOE.gguf(约 17 GB)。它不做投机解码,所有 Nemotron-H 都不做:主干的多 token 验证与单 token 解码走的是不同的注意力与 MoE 内核,投机输出无法与普通贪心解码一致(2026-09-16 用 NVIDIA 为该模型提供的 DSpark 草稿器测试时,每个单独请求都出现了偏离)。--draft-model 会被拒绝——服务端在启动时直接停止——而 --spec 会给出一次性警告并按普通解码运行。→ 支持块级起草的家族如何工作

Hunyuan Dense(仅文本,单设备)

腾讯的稠密 Hunyuan 解码器——即 general.architecture 为 hunyuan-dense 的检查点,例如 Hy-MT2 系列。在该架构注册之前,这些官方文件会在加载阶段失败:加载器遇到未知架构选择失败关闭,而不是猜一套相近的图。文本计算图与 llama.cpp 的 hunyuan-vl 文本塔一致——RMSNorm、融合 QKV、NeoX RoPE,然后是 per-head Q/K RMSNorm、GQA 与 SwiGLU。QK-norm 在 RoPE 之后,与 Qwen 3.5 相反;搞反了不会加载失败,只会产出流畅但错误的文本,所以这两个 norm 是必需的,缺失即抛异常。

# 任何 general.architecture 为 hunyuan-dense 的 GGUF 都可以,选择依据不是文件名
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll \
    --model models/<your-hunyuan-dense>.gguf \
    --backend ggml_cuda --input prompt.txt --max-tokens 200

第一版:仅文本、单设备、走通用 per-op 路径,没有思考通道也没有工具解析器。多余的 GPU 会闲置,启动时会明说,而不用去猜。

Mistral 3(文本 + 图像)

hf download bartowski/mistralai_Mistral-Small-3.1-24B-Instruct-2503-GGUF mistralai_Mistral-Small-3.1-24B-Instruct-2503-Q4_K_M.gguf --local-dir models
hf download bartowski/mistralai_Mistral-Small-3.1-24B-Instruct-2503-GGUF mmproj-mistralai_Mistral-Small-3.1-24B-Instruct-2503-f16.gguf --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/mistralai_Mistral-Small-3.1-24B-Instruct-2503-Q4_K_M.gguf \
    --mmproj models/mmproj-mistralai_Mistral-Small-3.1-24B-Instruct-2503-f16.gguf \
    --image photo.png --max-tokens 300 --backend ggml_cuda
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/mistralai_Mistral-Small-3.1-24B-Instruct-2503-Q4_K_M.gguf \
    --mmproj models/mmproj-mistralai_Mistral-Small-3.1-24B-Instruct-2503-f16.gguf --backend ggml_cuda

Muse-Glimmer(文本 + 图像、思维链、工具、DFlash 起草)

hf download unsloth/Muse-Glimmer-30B-GGUF Muse-Glimmer-30B-UD-IQ2_XXS.gguf --local-dir models
hf download unsloth/Muse-Glimmer-30B-GGUF mmproj-Muse-Glimmer-30B-Q8_0.gguf --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/Muse-Glimmer-30B-UD-IQ2_XXS.gguf \
    --input prompt.txt --max-tokens 256 --backend ggml_cuda
# 图像理解
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/Muse-Glimmer-30B-UD-IQ2_XXS.gguf \
    --mmproj models/mmproj-Muse-Glimmer-30B-Q8_0.gguf --image photo.png --input question.txt \
    --max-tokens 300 --backend ggml_cuda
# DFlash 投机解码(草稿 GGUF 可从同仓库下载)
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/Muse-Glimmer-30B-UD-IQ2_XXS.gguf \
    --draft-model models/dflash-kquant.gguf --spec-draft 15 --input prompt.txt --backend ggml_cuda

Muse Spark(816B 稀疏 MoE,文本 + 图像、思考、工具)

Unsloth 发布的 Muse-Spark-Open-816B-A42B 声明 general.architecture = muse-spark(别名 muse_spark):总参数 816B,每 token 激活约 42B;62 个块,隐藏宽度 8192,128 个 query 头 / 16 个 KV 头,head dim 64;256 个路由专家,按 sigmoid 路由取 top-8,专家潜空间宽 4096。其中 46 层是带 RoPE 的 2048 token 滑动窗口层,其余 16 层是全局 NoPE 层。元数据自报 1,048,576 token 的上下文,但这一点未经验证:不设 MAX_CONTEXT 时,原生执行器会把上下文限制为装得下的最大长度并写入日志;设了 MAX_CONTEXT 而装不下时则拒绝加载。这是一个需要多 GPU 服务器的模型:实测环境是十张 A40(各 46 GB),UD-IQ3_XXS 量化的全部专家都放在显存里;GPU 更少时,显存放不下的专家堆栈会留在主机内存里,主机内存就得足够大。TensorAgent 的模型目录不包含它。

# UD-IQ3_XXS 为 8 个分片、317 GiB(UD-Q3_K_XL 为 10 个,UD-Q4_K_XL 为 12 个)——同一量化的所有分片放在同一个目录里
hf download unsloth/Muse-Spark-Open-816B-A42B-GGUF --include "UD-IQ3_XXS/*" --local-dir models/muse-spark
# 图像投影器(2.2 GB),位于仓库根目录
hf download unsloth/Muse-Spark-Open-816B-A42B-GGUF mmproj-Q8_0.gguf --local-dir models/muse-spark

# 实测配置:十张 A40、全部专家在显存中、32K 上下文、规划 5 个槽位 —— --model 指向该组中的任一分片均可
MAX_CONTEXT=32768 TS_MUSE_SPARK_PLAN_SLOTS=5 TS_CODE_EXEC=0 \
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/muse-spark/UD-IQ3_XXS/Muse-Spark-Open-816B-A42B-UD-IQ3_XXS-00001-of-00008.gguf \
    --backend ggml_cuda --layer-split 10 \
    --host 127.0.0.1 --port 8083 --no-webui --no-skills --no-multi-agent
# 用 --tp 10 代替 --layer-split 10 会把每一层切分到十张 GPU 上:decode 更快,长提示 prefill 更慢

后续分片不是独立模型:TensorSharp 从第 1 个分片读取架构、分词器与模型设置,再从完整的分片集合加载张量。--no-webui --no-skills --no-multi-agent 与基准运行保持一致——需要 Web UI、Agent Skills 与子智能体时去掉即可。规划的 5 个槽位容纳 4 个并发请求外加共享前缀检查点。需要图像输入时加上 --mmproj models/muse-spark/mmproj-Q8_0.gguf,并用 TS_MUSE_SPARK_DEV0_RESERVE_MB 在 GPU 0 上为视觉编码器留出空间(十张 A40 的运行没有加载投影器)。GPU 更少时,TS_MUSE_SPARK_CPU_MOE=auto 会把放不下的专家堆栈留在主机内存里。

在 ggml_cuda 与 ggml_vulkan 上,它默认走 TensorSharp 自有的原生整模型执行器:执行器自己加载分片 GGUF,每个微批(prefill 微批为 2048 token)向所有 GPU 与 CPU 提交一张 GGML 图,用的是未经修改的上游 ggml。--layer-split N 把 62 层分布到 N 张 GPU 上并让各 GPU 的占用尽量均衡,最多 16 张(无法满足的数量会被拒绝,而不是在更少的 GPU 上运行);TS_MUSE_SPARK_CPU_MOE=auto 则对每层的 gate、up、down 专家堆栈分别放置:能放进 GPU 的尽量放进去,留在主机上的字节尽量少。它会覆盖 --n-cpu-moe N——后者是把前 N 层的专家强制放到主机上;两者都不设时,装不下的模型会被拒绝,报错信息会点名该选项。在多路 CPU 的主机上,主机侧专家堆栈会被复制到 NUMA 本地内存,由绑核的工作线程执行;2–16 token 的批次交给 TensorSharp 自有的静态行内核,结果与 ggml 逐位一致。TS_MUSE_SPARK_NATIVE=0 选择较早的逐算子路径,TS_MUSE_SPARK_NATIVE=1 则让 GGML CPU 后端也使用该执行器。整模型实测只在 ggml_cuda 上进行:Vulkan 默认同样选择该执行器,但没有任何整模型运行记录。

在两张或更多 CUDA GPU 上、且全部专家都在显存中时,按层切分会流水线式 prefill:每次提示调用被切成等大的微批,GPU k 处理一个微批时 GPU k+1 处理前一个,与 llama.cpp 的流水线并行相同。微批大小按调用决定——约为调用的四分之一,介于 512 与 2,048 行之间,长上下文的掩码放不进暂存缓冲时会更小——除非用 TS_MUSE_SPARK_PIPELINE_UBATCH 固定;TS_MUSE_SPARK_PIPELINE=0 关闭流水线,1 则要求启用,加载日志会说明实际情况。只有一个提示时,调度器让模型决定 prefill 步长——8,192 token,较短的余数并入前一步——除非设置了 TS_SCHED_SOLO_PREFILL_CHUNK。在实测的十张 A40 运行中,按层切分每张 GPU 约占 36 GiB,加载约 6 分钟。

在 ggml_cuda 上,--tp N 以张量并行方式运行同一个原生执行器:通过上游 ggml 的 meta 后端(即 llama.cpp -sm tensor 背后的机制)把每一层切分到前 N 张 CUDA GPU 上(用 CUDA_VISIBLE_DEVICES 选择)。注意力按 KV 组切分,路由专家沿隐藏维度切分,输出头按词表行切分,每层以两次 all-reduce 结束;TensorSharp 会先探测 peer 拷贝,P2P 不可用时让 NCCL 走共享内存。全部专家必须放进显存,因此 --n-cpu-moe N 会被拒绝;TS_MUSE_SPARK_LAYER_SPLIT、TS_MUSE_SPARK_PIPELINE=1 以及超过 16 个 KV 头的 N 同样会被拒绝;流水线 prefill 与推测解码在此模式下关闭。TS_MUSE_SPARK_NATIVE=0 保留较早的逐算子 TP 路径,ggml_vulkan 上的 --tp N 也走这条路径:按 GQA 头组切分注意力、以整个专家为单位划分专家,允许不均匀划分(例如九张 GPU),且仅限单节点。

每个请求拥有一个 F16 的按序列 KV 槽位——滑动层用环形缓冲区,全局层的行按需增长——decode 在各槽位之间批处理(文本与图像请求都适用),同时到达的新文本提示也会一起批量 prefill。前缀缓存可以从已完成的槽位续接对话、回退已完成的对话以重新生成回答,并把共享的系统提示词 / 模板前导检查点克隆进新对话;互不相关的对话只共享这段公开前缀。

图像以 OpenAI image_url 内容部分或 CLI 的 --image 传入,经由共享的 Muse-Glimmer 视觉编码器与该发布自带的 mmproj-Q8_0.gguf 处理;Muse-Glimmer-30B 的投影器会被拒绝,也没有音频输入。思考与工具沿用 Muse-Glimmer 的通道协议:模型在 assistant to=self 消息里推理、在 assistant to=user 中作答,模板还会渲染推理等级(low / medium / high / xhigh);ATEM XML 工具调用按 to= 接收方头部路由,另有一个 commentary 通道——因此 Agent Skills 享有完整的渐进式披露,子智能体委派也会提供给它。response_format 可以与 "think": true 组合:JSON 语法在 to=user<|message|> 之后才开始约束。该模型需要 GGUF 内嵌的聊天模板,没有通用回退。推测解码只有无权重的 n-gram 草稿器(--spec --spec-type ngram),没有训练过的草稿模型。

报告更新于 2026-10-22,未记录实际测量日期:十张 A40、UD-IQ3_XXS、全部专家驻留显存、32,768 上下文、F16 KV、关闭思考。按层切分的 4,075 token 提示 prefill 为 999.7 对 483.2 tok/s(2.07×,单请求、输出上限 32);张量并行的单请求 decode 为 22.63 对 16.19 tok/s(1.40×,167 token 提示、输出上限 256),四并发总输出为 45.73 对 24.49 tok/s(1.87×)。两者对照 llama.cpp 的对应模式,参照 TP 各行只有两次重复;主机没有可用 P2P,参照构建未启用 NCCL。计时方法、质量与完整局限 → Muse Spark 晚于 v2026.10.11 发布标签,需要源码构建。模型卡与验证范围 →

MiniMax-M3.1-Flash(428B 稀疏 MoE,文本 + 图像、思考、工具、DSpark)

MiniMax-M3.1-Flash(由 Unsloth 转换)声明 general.architecture = minimax-m3(别名 minimax_m3):总参数 428B、每 token 激活约 23B;60 层、隐藏宽度 6144(3 个稠密层,其后 57 个 MoE 层,128 个路由专家 top-4 加 1 个共享专家);64 个 query / 4 个 KV 头,头维度 128;每一层都是 MiniMax 稀疏注意力:索引器为每个 KV 头选出 16 个 128 行的块,因此位置 2048 之前的注意力就是精确的稠密注意力。路由专家为带逐专家缩放的 NVFP4。这是多 GPU 服务器模型:UD-Q4_K_XL 为 232.3 GiB,实测环境是八张 A40(每张 46 GB)。它只在 ggml_cuda 上运行(ggml_cpu 为正确性路径;MLX、Metal、Vulkan、直连 CUDA 与纯 C# 后端都会拒绝),也不在 TensorAgent 目录中。

# UD-Q4_K_XL 为 7 个分片、232.3 GiB——放在同一目录
hf download unsloth/MiniMax-M3.1-Flash-GGUF --include "UD-Q4_K_XL/*" --local-dir models/minimax-m3

# 除非用 --layer-split N 或 --tp N 指定,TensorSharp 只使用一张 GPU;该模型需要多张
MAX_CONTEXT=73728 TS_MINIMAX_M3_PLAN_CTX_TOKENS=147456 \
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll \
    --model models/minimax-m3/UD-Q4_K_XL/MiniMax-M3.1-Flash-UD-Q4_K_XL-00001-of-00007.gguf \
    --backend ggml_cuda --layer-split 8 --port 5000
# 用 --tp 8 代替 --layer-split 8 时每层切分到八张 GPU:decode 更快,浅深度时尤其明显
# 可选:--mmproj models/minimax-m3/mmproj-MiniMax-M3.1-Flash-BF16.gguf(图像)
#       --draft-model models/minimax-m3/MiniMax-M3.1-Flash-DSpark-BF16.gguf(DSpark,仅按层切分)

Unsloth 仓库标注为仍在制作中,目前没有 mmproj,也没有 DSpark 草稿器。两者都用 unslothai/llama.cpp PR #320(分支 minimax-m31,ef8f94cc)的转换器从 Hugging Face 发布版转换:投影器用 convert_hf_to_gguf.py <hf-dir> --mmproj --outtype bf16,草稿器用 convert_hf_to_gguf.py <hf-dir>/dspark --target-model-dir <hf-dir> --outtype bf16 --outfile …。只需要配置与分词器文件、第 13 与 48 个 safetensors 分片(视觉塔;给 mmproj 步骤一个只列出这两个分片的索引)以及 dspark/。完整步骤 →

TensorSharp 自有的原生整模型执行器自行加载分片 GGUF,在未修改的上游 ggml 上每个微批提交一张 GGML 图。--layer-split N 把整层放到最多 16 张 GPU 上,并把一个提示的 prefill 以流水线方式分布到各 GPU;--n-cpu-moe N 从系统内存提供第 0..N-1 层的路由专家(第 0-2 层是稠密层),TS_MINIMAX_M3_CPU_MOE=auto 只放置放不下的专家栈。--tp N 在上游 ggml 的 meta 后端上用前 N 张 CUDA GPU 运行执行器:由于只有四个 KV 头,注意力、索引器与缓存在每张 GPU 上镜像而 FFN 切分,因此每张 GPU 能容纳的上下文更少(八张 A40 上为 45,824 token),并且拒绝主机专家与草稿器。TS_MINIMAX_M3_MSA 选择注意力路径:auto(2048 之前稠密,之后用 TensorSharp 的 CUDA MSA 内核)、dense、ggml 或 kernel。每个请求拥有 K、V 与索引键的 F16 逐序列槽位(每 token 135 KiB);decode 跨槽位批处理,并发的文本提示一起 prefill,前缀缓存可续写、精确回退,并克隆共享的系统提示检查点。

聊天模板由 TensorSharp 自己的渲染器逐字节一致地渲染。思考是自适应的:模型逐轮决定是否打开 <mm:think>,"think": true 可强制开启,没有关闭开关;reasoning_effort 渲染为 <effort>。工具调用是命名空间 XML,按声明的 schema 推断类型;tool_choice 为 required / 指定函数以及 response_format JSON 时,在 </mm:think> 之后由语法强制。DSpark 草稿器(--draft-model)在累积置信度门限 0.35 下提出最多 7 个 token 的块。图像经由转换得到的投影器;视频以抽样帧输入;拒绝音频。

2026-10-24 在八张 A40 上测量,对照 llama.cpp minimax-m31(ef8f94cc),三次重复:按层切分时,32K token 提示的服务器 prefill 为 1,544 对 240 tok/s(6.43×),4K 深度 decode 为 23.9 对 19.2(1.24×);八个并发请求的聚合输出为 53.7 对 40.6 tok/s;DSpark 为 32.3 对 25.8 tok/s;--tp 8 深度 0 的 decode 为 35.7 tok/s(llama.cpp 对该模型没有张量切分)。短对话首 token 时间略慢,0.41 对 0.39 s。所有单元、方法与限制 → MiniMax-M3.1 晚于 v2026.10.11 发布标签,需要源码构建。模型卡与验证范围 →

DiffusionGemma(分块文本扩散,文本 + 图像)

hf download unsloth/diffusiongemma-26B-A4B-it-GGUF diffusiongemma-26B-A4B-it-Q4_K_M.gguf --local-dir models
# 可选,用于图像输入:视觉塔不在任何 GGUF 里,只在这个上游分片中(2.84 GB)
hf download google/diffusiongemma-26B-A4B-it model-00011-of-00011.safetensors --local-dir models

dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/diffusiongemma-26B-A4B-it-Q4_K_M.gguf --input prompt.txt \
    --max-tokens 256 --diffusion-steps 48 --diffusion-seed 0 --backend ggml_cuda
# 针对图片提问(多张图片可重复 --image,按顺序)
dotnet TensorSharp.Cli/bin/TensorSharp.Cli.dll --model models/diffusiongemma-26B-A4B-it-Q4_K_M.gguf \
    --mmproj models/model-00011-of-00011.safetensors --image photo.png --input question.txt \
    --max-tokens 256 --backend ggml_cuda
dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/diffusiongemma-26B-A4B-it-Q4_K_M.gguf \
    --mmproj models/model-00011-of-00011.safetensors --backend ggml_cuda

该检查点发布的所有 GGUF 都是纯文本的,因此 Gemma 4 视觉塔(gemma4v)直接从上游 model-00011-of-00011.safetensors 分片加载,也可以来自 mmproj GGUF;两个宿主都不会在模型旁边自动查找它,没有加载时图像请求会被拒绝,而不是在看不到图的情况下作答。config/diffusiongemma-26b-a4b-q4.json 与 -q3.json 会替你下载该分片。音频会被拒绝——检查点没有音频塔——视频同样会被拒绝,请把帧作为单独的图像发送。提示词始终以关闭思考的方式渲染:模型自发写出的思考块只有在 "think": true 时才作为推理内容返回。带工具的请求会以 HTTP 400 拒绝。

同一个服务端还在 POST /v1/systemone 上回答类型化决策,这是兼容 Jev 的端点:针对文本或图像状态(每个请求最多 8 张图)的 noul(布尔)、choice 与 score 问题,答案取自一次去噪步后的标签概率,而不是解析生成的 JSON。jev-latest 与 jev-preview 是已加载模型的别名,并不是单独的检查点。config/jev-diffusiongemma-q4.json 会下载模型与视觉分片,并在 ggml_cuda 上绑定 127.0.0.1:5000;请求格式见 Jev 卡片。

多模态支持

家族输入说明
DeepSeek V4.1图像 · 视频另行准备的视觉伴随文件 deepseek41.vision.gguf(由 eng/dsv41-prepare-vision.py 生成),通过 --mmproj 传入。视频被采样为带时间的帧,走图像路径(OpenAI video_url 内容部分,默认 1 fps、16 帧),而不是时序编码器。该伴随组件是原生 ggml 组件,因此纯 C# 的 cpu 后端仅文本。音频会以 HTTP 400 拒绝。
Gemma 4图像 · 视频 · 音频图像 PNG/JPEG/HEIC;视频 MP4(经 OpenCV 以 1 fps 采样);音频 WAV 16 kHz 单声道 / MP3 / OGG。E4B 投影器:mmproj-gemma-4-E4B-it-Q8_0.gguf。
Qwen 3.5 / 3.6图像动态分辨率视觉编码器;9B / 3.6 仓库使用 mmproj-F16.gguf。
Bonsai2 27B图像Qwen 3.5 视觉塔,来自 Ternary-Bonsai-2-27B-mmproj-BF16.gguf 或 -mmproj-Q8_0.gguf;CLI 会在模型旁边查找它们(优先 BF16)。
Qwen 3.8 Flash Next图像 · 视频Qwen3.5-VL 视觉塔,使用 (T,H,W) IMRoPE 位置;支持多图提示与多轮图像会话;跨轮 KV 复用止于第一个图像或视频片段。视频以 OpenAI video_url 内容部分传入(base64 MP4 / WebM / MOV),采样为带时间的帧——每个部分可设 fps 与 max_frames,默认取 VIDEO_SAMPLE_FPS / VIDEO_MAX_FRAMES,否则为 1 fps、16 帧——并按 Qwen-VL 的时间 patch 布局排列。投影器:mmproj-BF16.gguf(同仓库)。
GLM 5.x(5.3-Flash)图像GLM-OCR ViT——24 个块作为一张常驻设备的图跑完,投影后的行在原生执行器内部覆盖 <|image|> 占位。支持多图与多轮图像会话。投影器:mmproj-BF16.gguf(同仓库)。GLM-5.2 与 GLM-5.3(glm-dsa)均仅文本:GLM-5.3 仓库在任何量化下都未发布 mmproj,且给 glm-dsa 传入 --mmproj 只会告警并忽略、不会报错,因此仍是一次纯文本运行。只有 glm5next 接受投影器。
Mistral 3图像Pixtral 视觉编码器。投影器:mmproj-mistralai_Mistral-Small-3.1-24B-Instruct-2503-f16.gguf。
Muse-Glimmer图像50 层稀疏窗口 ViT,采用 2D RoPE 与 2×2 像素混洗;图像按 llama.cpp 相同的方式选定网格后直接拉伸(不填充、不切块)。投影器:mmproj-Muse-Glimmer-30B-Q8_0.gguf。
Muse Spark图像共享的 Muse-Glimmer 视觉编码器,配合该发布自带的 mmproj-Q8_0.gguf(仓库根目录)。它的投影器类型是 muse-glimmer,但 8192 宽的输出必须与 Spark 解码器匹配,因此 Muse-Glimmer-30B 的投影器会被拒绝。图像以 OpenAI image_url 内容部分或 CLI 的 --image 传入;投影器里带有音频塔也不会启用音频。
MiniMax-M3.1图像 · 视频(抽样帧)32 块 ViT、投影器与 2×2 patch 合并来自 clip.projector_type = minimax_m3 的 mmproj,需从 Hugging Face 发布版转换(目前没有公开发布),通过 --mmproj 传入。每张图 4 到 576 个 token,最多相当于 672×672 像素;图像行在原生执行器内替换占位符。video_url 部分会被抽成带时间的帧走图像路径(未在真实模型上测量)。拒绝音频:该发布没有音频塔。
Nemotron-H (Omni)图像(配伴随文件时支持音频)RADIO / v2_vl ViT 编码器。传入匹配的 --mmproj;图像 token 在 <image> 占位处展开。音频只有在加载了另行准备、带 Parakeet 音频塔的伴随 GGUF(--mmproj 或 TS_NEMOTRON_AUDIO_MMPROJ)时才运行;没有公开仓库提供该文件,缺少时音频会被拒绝。
DiffusionGemma图像Gemma 4 的 gemma4v 视觉塔,通过 --mmproj 从上游 model-00011-of-00011.safetensors 分片(或 mmproj GGUF)加载。图像可用于聊天,也可用于 /v1/systemone 决策(每个请求最多 8 张)。音频与视频会被拒绝。

通过 CLI(--image、--video、--audio、--pdf)、Web UI 上传,或 HTTP API(Ollama 用 base64 images 数组,OpenAI 用 image_url data URI)发送文件。数字版 PDF 会提取完整文本层并内联到提示中;扫描版 PDF 会转换为页面图像,需要支持视觉的模型。CLI 的 --pdf 仅用于一次性模式;CLI 与 Web UI 上传都由 TS_PDF_MAX_PAGES 限制页数(默认读取全部页)。

思考 / 推理模式

具备思考能力的模型(Qwen 3.5/3.6、Qwen 3.8 Flash Next、Gemma 4、GPT OSS、Nemotron-H、DeepSeek V4、DeepSeek V4.1、GLM 5.x、Muse-Glimmer、Muse Spark、MiniMax-M3.1)会在最终答案前产生结构化的思维链。思考内容与可见回复分离,便于客户端显示或隐藏。

通过 --think(CLI)、"think": true(Ollama API / Web UI)或浏览器中的思考开关启用。响应会单独暴露推理 —— 例如 Ollama 聊天响应中的 message.thinking。

工具调用 / 函数调用

受支持的模型家族可以调用用户自定义工具,并参与多轮工具调用对话。将工具定义为 JSON,通过 --tools(CLI)或 tools 参数(API)传入。每个受支持架构使用各自的线格式,其输出解析器会将调用提取为结构化 tool_calls:

Mistral 3、Hunyuan Dense 与 DiffusionGemma 不在此列表中:前两者既不渲染工具声明也不渲染工具结果,DiffusionGemma 会拒绝带工具的请求,因此客户端工具、内置技能 / 代码工具与子智能体委派都不会提供给它们;选中的 Agent Skill 指令会作为无工具回退直接内联。

完整的请求/响应示例与续接循环见 通过 HTTP 进行工具调用。