把 284B 的 DeepSeek V4 Flash 装进纯 .NET:TensorSharp 用一天改写了 .NET 推理栈的位置

2026 年 7 月 31 日,星期五。

上午,zhongkaifu/TensorSharp仓库合并了 PR #116------DeepSeek V4 Flash(下称 DSV4)正式接入 TensorSharp.Server,拿到 OpenAI 兼容接口和 continuous batching 多并发能力。当天晚上,作者 Zhongkai Fu 又推上了一个新分支:feature/update_direct_cuda_backend_to_support_deepseek_v4,为 DSV4 手写了一条完全绕开 ggml 的直接 CUDA 后端。

一天之内,从「能跑」到「能服务」,再到「能用自己写的 CUDA kernel 跑」。

这件事值得认真对待,因为 DSV4 不是一个玩具模型:它是一个 284B 参数、256 个专家的顶级开源权重 MoE。在 TensorSharp 之前,没有任何纯 .NET 技术栈能把它从头到尾跑起来。而现在,它不仅能跑,还能多并发地对外提供服务。

一个长久以来被视为「推理玩具」的技术栈,第一次摸到了「可用选项」的门槛。

先交代一下背景,方便不熟悉推理引擎的读者进入状态。所谓推理栈,就是把模型权重加载进内存/显存、逐层执行前向计算、逐 token 吐出结果的那一整套软件。过去几年,这个领域几乎是 C++/CUDA 和 Python 的天下:llama.cpp 用极致的 C 工程统治了本地推理,vLLM 用 PagedAttention 统治了服务端吞吐。而 .NET 开发者想用大模型,标准姿势只有一个------调云端 API,或者在旁边起一个外部进程,用 HTTP 把请求递过去。语言生态的边界,就是推理能力的边界。TensorSharp 想改写的,正是这条边界。

这个模型为什么难跑

先看清对手。DSV4 的架构几乎处处都在挑战推理引擎的常规假设:

  • 稀疏 MoE:284B 总参数,256 个 routed experts,每个 token 走 top-6 路由,外加 1 个常驻的 shared expert。权重体量决定了它必然是显存与带宽的双重怪兽------IQ4_XS 量化后仍有约 128 GiB,需要 2×80GB 的显卡才装得下。
  • 极度吝啬的注意力窗口:每层只有 128 token 的原始滑动窗口(SWA)。128,不是 128K。长上下文能力全部押注在压缩注意力上:CSA 按 4:1 块压缩 keys,HCA 按 128:1 块压缩 keys,再由一个 lightning indexer 在 CSA 层上动态选出 top-512 的压缩行参与注意力。
  • 非常规的残差结构:残差流不是一条路,而是 4 流 hyper-connections,混合权重经 Sinkhorn 归一化。这意味着 kernel 层面有一整块别人没有的计算图。
  • 标称 1M token 上下文(YaRN ×16 外推)。TensorSharp 出于务实,默认 MAX_CONTEXT=65536。

对推理引擎来说,这不是「换个权重文件」就能支持的新模型,而是一套需要逐层定制 kernel 的全新架构。这也是为什么社区里为它专门写实现的(antirez 的 ds4、vLLM 的 DSpark)都是硬骨头项目。

三条推理路径:TensorSharp 的务实主义

面对这样一个模型,TensorSharp 给出的不是单点答案,而是三条并行的推理路径。理解这三条路径,就理解了 TensorSharp 的工程哲学:不赌单一路线,用架构冗余换可用性。

路径 技术形态 依赖 定位
直接 CUDA 后端(新增) 手写 29 个 DSV4 专用 CUDA kernel + CUDA Driver API + cuBLAS 仅 NVIDIA 驱动,不依赖 ggml 主力 GPU 性能路径
ggml_cuda / ggml_vulkan 原生 ggml 全模型执行器 + CUDA graph 重放 ggml 跨平台 GPU 路径(CUDA/Vulkan)
纯 C# CPU 后端 100% 托管代码 + 托管 SIMD 整数量化点积 kernel 零原生依赖 兜底与可审计路径

路径一:直接 CUDA 后端------最硬的一块骨头

这是 7 月 31 日晚提交的新分支的核心。代码体量本身就是态度:Dsv4CudaEngine.cs 1354 行、Dsv4Kernels.cs 379 行、tensorsharp_dsv4_kernels.cu 2204 行 CUDA 源码(外加 5.5 万行预编译 PTX)、DeepSeek4CudaExecutor.cs 471 行。

29 个 DSV4 专用 CUDA kernel,覆盖了架构里所有的「非标件」:hyper-connection 的 Sinkhorn 混合、CSA/HCA 的块压缩、lightning indexer 的 top-512 选择、MoE 的 scatter 与 staged gate-up-down、SWA 环形缓存。整条路径通过 CUDA Driver API 加 cuBLAS 驱动------完全不依赖 ggml,这是与 llama.cpp 系路线最本质的分野。

多卡与显存策略同样明确:量化权重常驻显存;按累计权重字节数在多块 GPU 之间做层切分;层边界处用 cuMemcpyPeerAsync 加 events 做跨卡流水,避免同步空转;cache 一律存 F16,与 llama.cpp 的精度口径对齐,便于横向比较。

路径二:ggml 后端------成熟生态的借力

如果环境里已有 ggml,TensorSharp 可以走 ggml_cuda / ggml_vulkan 的原生全模型执行器,配合 CUDA graph 重放缓存和一个按 shape 签名键控的 graph cache。这条路线的价值在于跨平台------尤其 Vulkan 后端,让非 NVIDIA 显卡也有入口。

路径三:纯 C# CPU 后端------.NET 的底线尊严

这条路径最容易被低估,却可能是 TensorSharp 对 .NET 生态最独特的贡献:100% 托管代码,零原生依赖。量化权重直接从 mmap 映射的 split-GGUF shard 读取,计算走托管 SIMD 加整数量化点积 kernel(Q8_0/Q6_K/IQ3_S/MXFP4 权重 × 量化激活),还可选配持久自旋工作池(TS_DSV4_SPINPOOL)压低线程调度抖动。

它不会是最快的,但它意味着:任何一个能跑 .NET 的机器,理论上都能加载并推理 DSV4------不需要 CUDA 工具链,不需要原生库,不需要信任任何二进制依赖。对看重可审计性与部署简单性的企业场景,这是实打实的差异化。

PR #116:从「能跑」到「能服务」

7 月 31 日上午合并的 PR #116,把 DSV4 从单机 demo 变成了一个真正的服务。TensorSharp.Server 现在可以对外提供 OpenAI 兼容的 /v1/chat/completions 接口、内置 Web UI chat,以及 continuous batching 多并发。

多并发是这里的技术重心,而它的实现方式值得展开:原生 sequence slot 机制

每一个 slot 独立拥有全套 per-layer cache------SWA 环形缓存、CSA/HCA 压缩 K cache、compressor 状态环、lightning indexer cache------以及自己的 n_past 位置指针。graph cache 按 slot id 键控,每个并发请求重放属于自己的那条 CUDA graph。在 4 GPU + 64K 上下文的配置下,每个 slot 约占用 520 MB 显存。slot 0 是主单流 slot,保证原有的 CLI 单请求路径完全不受影响。

这套隔离设计有一个近乎苛刻的验收标准,而它通过了:

每个并发 slot 的输出,与该请求单流运行、温度为 0 时的结果逐字节一致。

逐字节一致。这意味着 slot 之间的隔离是精确的,没有任何状态串扰------continuous batching 里最常见的「并发漂移」问题,在这里被从源头上排除了。

为什么要把验收标准定得这么苛刻?因为并发推理服务一旦上线,状态串扰是最难排查的一类故障:它不报错,只是让某个用户的输出「悄悄变差」,而这种劣化往往要到业务侧才能感知。用温度 0 的确定性解码做逐字节比对,等于把「并发是否正确」这个模糊问题,转化成了一个可自动化、可回归的精确断言。这是测试设计上的功力,也是对生产环境的尊重。配合的测试基座同样扎实:4×A40、133 GB 模型、4 卡层切分;调度器与执行器单元测试 60/60 全过;同构建下 gemma-4-26B 回归无损。

还有一个注脚级的细节,反而最能说明工程的严谨度:PR 顺带修复了 BatchExecutor 的一个隐藏 bug------fused 路径上,FRESH holder 可能携带一个未 adopt 的 live-cache continuation claim,导致模型对着空 cache 在非零位置解码。修复方式是干脆丢弃这个 claim,从头重新 prefill。这类 bug 只有在真实多并发压力下才会暴露,而它被逮住了。

性能基线:诚实的第一版数字

性能部分,先看数据(2×A100 80GB,IQ4_XS,约 128 GiB 权重):

指标 TensorSharp llama.cpp(同机)
Prefill(3.3K prompt) ~500 tok/s 574(pp512)/ 634(pp4096)
Decode @3.3K ctx ~33 tok/s 40.3(tg128)

两个值得注意的点。

第一,TensorSharp 的首版性能已经在 llama.cpp 的同一数量级------prefill 约为其八到九成,decode 约八成。对一个完全绕开 ggml、自行实现全部 kernel 的新后端,这个起点相当高,且优化空间(更激进的图融合、kernel 调优)清晰可见。

第二,正确性证据比速度更重要:4.6K 与 15K 的大海捞针(needle)测试均精确命中。这说明压缩注意力路径真实生效------模型确实能检索远超 128 token 原始滑动窗口的信息。kernel 写对了,架构理论在工程上兑现了。

部署门槛也顺带明确了:128 GiB 的 IQ4_XS 权重需要 2×80GB 显卡;稍大的 133 GB 模型则可以在 4×A40(48GB)上通过层切分跑起来。这是工作站/小型服务器集群够得着的配置,不是数据中心的专利。

放到生态里看:.NET 的独特价值在哪里

为 DSV4 写推理实现的,TensorSharp 不是唯一。antirez 的 ds4 走极简 C 路线,vLLM 的 DSpark 走 Python 生态的高吞吐路线。TensorSharp 的坐标需要放在自己的轴上看:

  • .NET 原生:不靠 WSL、不靠容器套娃,直接融进现有 .NET 企业的部署体系。
  • 托管代码可审计:从权重加载到 kernel 调度,整条链路是可读、可审、可单步调试的 C#。对金融、政企这类有合规要求的场景,这一点比 10% 的性能差距更值钱。
  • GGUF 直读:复用社区已有的量化生态,不引入私有格式。
  • 纯 C# CPU 兜底:没有 GPU 的环境也能跑,给出一条「永远可用」的下限。

更宏观地看,.NET 生态这两年在 AI 应用层(Semantic Kernel、 Microsoft Agent Famework、OpenClaw.NET)进展很快,但推理层长期依赖外部进程------llama.cpp、vLLM、Ollama,总要跨进程、跨语言调一个「别人的引擎」。TensorSharp 把推理引擎本身变成了 .NET 进程内的一等公民。当推理栈、Agent 运行时、业务代码说同一种语言、活在同一个进程里,部署拓扑、调试体验和运维成本都会发生质变。

结语:两个「第一次」

回到开头的判断。7 月 31 日这一天,TensorSharp 实际上立下了两个里程碑:

第一个属于 .NET:一条 .NET 推理栈第一次从「玩具」变成了「可用选项」。284B 参数的顶级模型、逐字节一致的多并发隔离、同数量级的性能基线、零原生依赖的托管实现------这些词以前不会同时出现在关于 .NET 的句子里。

第二个属于整个本地 LLM 领域:DeepSeek V4 Flash 可能是第一个成本合理且可用的本地部署大模型。2×80GB 的门槛意味着几张消费级到工作站级的显卡就能私有部署一个 284B 的前沿模型,数据不出机房,成本可以精确预算。

当顶级模型权重持续开源,推理栈的竞争就不再是「谁能跑」,而是「谁能更好地嵌入生产环境」。.NET 刚刚拿到了这张牌桌的入场券------而且是用自己写的 CUDA kernel 拿到的。


信息来源(截至 2026-08-01):

  • GitHub 仓库:zhongkaifu/TensorSharp
  • PR #116(DSV4 服务化 + continuous batching,2026-07-31 合并)
  • 分支 feature/update_direct_cuda_backend_to_support_deepseek_v4(直接 CUDA 后端,2026-07-31 提交)
  • 仓库文档:docs/models/deepseek4.md