两个推理运行时藏在一套 API 后面,三种执行提供器,以及一个花了 CI 工作流才解决的原生依赖问题。本页是 AI 层的机械部分: 什么在跑模型,以及那要你在字节上付出什么代价。
不存在单个能覆盖每个值得跑的模型的本地推理运行时,所以这一层 两个都带。ONNX Runtime 用硬件执行提供器处理图模型。 GGML — 通过 llama.cpp 和 GGUF 格式 — 处理量化 语言和音频模型,那里是量化生态的所在地。
| 能力 | 运行时与格式 | 模型 |
|---|---|---|
| 文本生成、翻译 | GGML · llama.cpp · GGUF | 任何 GGUF 聊天或指令模型 |
| 图像生成与编辑 | ONNX Runtime | SD1.5、SDXL、SD3.5、Qwen-Image-Edit、Flux.2-Klein、Ovis、LongCat |
| 视频生成 | ONNX Runtime | 与图像共用代码路径 |
| 音乐生成 | ONNX Runtime | StableAudio |
| 语音转文字 | GGML · GGUF | Whisper |
| 文字转语音 | 两者 — ONNX 与 GGML | 可选说话人,外加从参考录音克隆声音 |
| 视觉、OCR | ONNX Runtime | 视觉语言与 OCR 模型 |
文字转语音是有意思的那一行:它在一个接口后带两个后端,因为好的 语音模型分散在两种格式里。这是「一套 API 盖在两个运行时上」买了 什么的最清晰例证 — 模型格式变了,调用代码不变。
| 提供器 | 硬件 | 可用性 |
|---|---|---|
| CPU | 任何设备 | 免费档 |
| DirectML | 任何 DirectX 12 GPU — NVIDIA、AMD、Intel、集成显卡 | 免费档 |
| CUDA | 仅 NVIDIA | 付费附加项 |
DirectML 是免费档不是象征性姿态的原因:它在几乎任何现代 Windows 机器上都是 GPU 加速的,包括集成显卡。CUDA 在支持的硬件上更快, 在不支持的硬件上毫无用处 — 这就是它待在付费档后面、而不是 被呈现为跑模型的那个方式的原因。
一个招牌卖点是 CUDA 的附加项,对 AMD 或 Intel GPU 用户毫无价值。 如果你用的是其中之一,诚实的建议是:免费档里的 DirectML 就是你 能得到的加速,付钱也改变不了这一点。
这是这一层实际上存在就是为了做的、不光彩的工作。在 Windows 上用
CUDA 跑 ONNX Runtime,意味着要附带一组 NVIDIA 运行时 DLL,它们的
版本必须彼此一致、并与加载它们的 ONNX Runtime 构建一致。错一个,
失败就是在生成时刻抛出一个
DllNotFoundException,发生在用户的机器上,
在他们已经装好你的应用之后。
仓库用 CI 工作流而不是文档页解决它。
.github/workflows/package-cuda-cudnn-runtime.yml
安装固定版本的 CUDA Toolkit,把固定版本的 cuDNN redist 放进去,然后只打包
应用需要的运行时 DLL:
cuda_version: 12.8.1
cudnn_version: 9.8.0.87
sub-packages:
cudart cublas cufft
curand cusparse
cusolver nvrtc
cudart64_*.dll cudnn64_*.dll
cublas64_*.dll cudnn_ops64_*.dll
cublasLt64_*.dll cudnn_cnn64_*.dll
cufft64_*.dll cudnn_adv64_*.dll
curand64_*.dll cudnn_graph64_*.dll
cusolver64_*.dll cudnn_heuristic64_*.dll
cusparse64_*.dll cudnn_engines_*64_*.dll
nvrtc64_*.dll
nvJitLink_*.dll
输出落在 runtimes/win-x64/native/,旁边是一个生成的
runtime-manifest.json,记录每个 DLL 的文件版本和
它来自的确切路径。如果两组 DLL 有任何一组回来是空的,工作流就
拒绝完成;而且它只从解析出的 CUDA_PATH\bin
复制,所以 runner 上预装的 toolkit 污染不了这个包。
manifest 带着这条注释,它值得重复,因为第一次看到时它像是个
bug:CUDA 11 及以后的版本让它们的 toolkit 组件独立版本化。
一个 CUDA 12.x 安装完全可能合法地同时带着
cudart64_12.dll、
curand64_10.dll 和
cufft64_11.dll。这正是为什么模式是
glob、版本被记录而不是被假设。
Windows App SDK 自带它自己的
onnxruntime.dll。如果你的应用打包为 MSIX 并且
还想要一个启用 CUDA 的 ONNX Runtime,SDK 的副本默认胜出,CUDA 就
悄悄永不生效。构建修复它的方式是在正常输出复制完成后,把自建的
运行时复制到最上面:
<Target Name="ReplaceWindowsAppSdkOnnxRuntime"
AfterTargets="CopyFilesToOutputDirectory"
Condition="'$(IsWindows)' == 'true'">
<ItemGroup>
<_SelfBuiltOrtDlls Include="..\..\..\cudacudnn-runtime\win-x64\native\*.dll" />
</ItemGroup>
<Copy SourceFiles="@(_SelfBuiltOrtDlls)" DestinationFolder="$(OutDir)"
OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" />
</Target>
SkipUnchangedFiles="false" 不是装饰 — SDK 的
DLL 和自建的 DLL 可能有相同的时间戳和大小,而 MSBuild 默认的最新
检查会把错的那个留在原地。这个 target 住在
Apps/Engine/Engine.csproj 里,意味着运行时包
必须放在仓库旁边的 ../cudacudnn-runtime/,
Windows 构建才能拿到它。
任何档位里,都没有模型文件随应用发布。权重大、单独授权、按自己的 节奏更新 — 把它们嵌进去会让每次应用更新都变成好几个 GB 的 下载,还悄悄让你成为别人许可证的再分发者。
| 关切 | 现状如何运作 |
|---|---|
| 权重从哪里来 | 每个面板链接到它在 Hugging Face 上的模型源仓库 |
| 谁下载它们 | 你手动下载 — 应用没有下载器 |
| 仓库中的网络代码 | 无 — 里面没有任何 HttpClient |
| 授权 | 各模型自己的条款适用;面板链接就是你读条款的地方 |
手动获取是真实的摩擦点,不是设计原则,而应用内模型管理器是 显而易见会想要的东西。它确实缺席,而直说这一点,好过让你装完 之后自己发现。
AI 层比引擎窄得多,在你围绕它做规划之前,值得先把这一点说直白。
| 平台 | AI 层 | 备注 |
|---|---|---|
| Windows | 完整 | CPU、DirectML 和 CUDA;打包的运行时就是为它准备的 |
| Linux | 部分 | 引擎能跑;打包的原生束只针对 win-x64 |
| Android、iOS、macOS | 不针对 | 模型大小和移动运行时是另一个问题 |
| Web | 无 | EngineWasm.csproj 只引用 Season.csproj |
Web 那一行不是正在绕开的限制 — 它是可验证的。WASM 应用的 项目文件恰好有一条项目引用,就是引擎。不存在 AI 能到达浏览器 构建的代码路径。