local-multimodal-infra
将本机及内网的 CPU / NVIDIA GPU 算力封装为可供 Agent 调用的多模态推理服务。
语音识别、语音合成、对话、向量与重排、视觉、OCR、内容审核、实时语音,全部在本地通过 ONNX Runtime 运行,以标准 MCP 和 OpenAI 兼容 API 提供给 Agent 与应用。
- 一套服务,多种接入:标准 MCP(推理 / 管理两个独立目录)、OpenAI 兼容 API(含实时语音 WebSocket 与内容审核)、旧版 JSON-RPC。
- controller / worker 架构:controller 管理模型目录、文件与任务并对外提供全部接口,worker 加载模型推理,可分布在多台机器。
- 模型按需加载:懒加载、并发限制、空闲卸载;CUDA 优先,CUDA 不可用或加载失败时回退 CPU(仅 GPU 的模型除外)。
- 可复现的模型:Hugging Face 文件固定到 commit,URL 文件固定 SHA-256 与大小;没有发布包的模型提供导出脚本。
- Rust 服务:controller / worker 均为 Rust,运行时不依赖 Python(Python 脚本只用于导出模型和测试);ONNX Runtime 在运行时动态加载。
支持的模型
获取方式:下载 = 管理接口一键下载;导出 = 没有发布的 ONNX 包,按文档从源模型本地导出。
语音识别 · 文档
语音合成 · 文档
对话 · 文档
文本向量与重排 · 文档
视觉 · 文档
OCR · 文档
内容审核 · 文档
实时语音 · 文档
“GPU”指 NVIDIA CUDA;标为 GPU 的模型按 GPU 设计与测量,CPU 只是回退(很慢),“仅 GPU”的模型拒绝在 CPU 上运行。“INT8 权重”指仅权重量化为 INT8,计算仍为浮点。模型规格按分类放在 configs/providers/<分类>/;配置字段、Provider 回退和如何覆盖模型配置见 模型配置。
快速开始
cp .env.example .env # 替换其中的占位 token
docker compose up -d --build # CPU
ORT_CUDA_VERSION=12 docker compose -f docker-compose-nvidia.yml up -d --build # 或 NVIDIA GPU
curl --fail http://127.0.0.1:17890/health
NVIDIA 版需要 Linux x86_64、支持 CUDA 12 的驱动、NVIDIA Container Toolkit 和 Compose 2.30+;只有 worker 使用 GPU(CUDA 12.8 + cuDNN 镜像),controller 用 CPU 镜像。模型不打进镜像,放在 ./workdir/models。
下载一个模型:
curl --fail-with-body http://127.0.0.1:17890/rpc/admin \
-H 'content-type: application/json' -H "x-local-admin-token: $LOCAL_ADMIN_TOKEN" \
--data '{"jsonrpc":"2.0","id":1,"method":"download_model","params":{"id":"sensevoice-small-onnx"}}'
端口暴露、源码构建与部署验证见 部署指南。
接入
Token:管理调用必须提供 LOCAL_ADMIN_TOKEN;LOCAL_MCP_INFER_TOKENS(逗号分隔)非空时保护所有推理接口,为空则推理不鉴权。均以 Authorization: Bearer <token> 发送(JSON-RPC 与 OpenAI 接口也接受 x-local-infer-token,管理接口接受 x-local-admin-token)。Compose 把 17890、17891 发布到所有网卡、MCP 端口只发布到本机回环;/v1/models、/health 不受推理 token 保护,请再用网络访问控制保护 controller 端口。
OpenAI 兼容与 HTTP 接口
只实现了下列接口,不是完整的 OpenAI API:
实时语音 /v1/realtime:客户端持续推送 16 kHz 16-bit 单声道 PCM,服务端回送 24 kHz 音频与 JSON 事件。两种模式:
- 级联模式(默认):服务端完成 VAD → SenseVoice → Qwen3 → TTS 的整个对话,支持插话打断、群聊唤醒词和客户端提供的发言人标注;需要客户端处理的任务以
tool.call(backend_task)交给客户端,客户端用tool.result/note回传。 - 音频模式(
"mode": "audio"):服务端只负责听和说,对话由客户端自己的模型完成(Codex 的本地语音用的就是此模式)。客户端收到带id/replaces/respond的input.transcript和state,用response.delta/response.end/response.cancel流式驱动服务端说话,每个回复结束时收到response.done(spoken为实际播出的部分);可开启moderation,转写交给客户端前先审核。
完整事件与配置见 实时语音协议。
MCP
推理目录 /mcp/infer 只有通用任务工具:list_models(已安装的模型、各自的任务类型,以及每种任务的文件、参数和输出)、run_task、create_task、start_task、wait_task、get_task、sign_assets。管理目录 /mcp/admin 负责下载、启用模型和查看集群。只把推理目录交给 Agent,不要给推理服务器配置管理 token:
{
"mcpServers": {
"local-multimodal": {
"type": "streamable-http",
"url": "http://127.0.0.1:17892/mcp/infer",
"headers": { "Authorization": "Bearer <推理 token>" }
}
}
}
LOCAL_MCP_INFER_TOKENS 为空时去掉 headers。旧版 JSON-RPC 的 /rpc/infer 另保留 asr_transcribe、tts_synthesize 等直接方法。全部接口、任务类型与大结果的 URL 返回见 API 文档。
作为 Rust 库
适配器 crate 也可以不经过服务、直接被应用(例如桌面客户端)以路径或 git 依赖引用:
local-adapter-sensevoice-asr:recognize_samples/recognize_samples_with_language识别一段 16 kHz 单声道音频(不经 VAD 流水线;语言 zh、en、yue、ja、ko 作为 SenseVoice 的语言提示,CUDA graph 同样生效);AudioStream、Resampler负责解码与重采样。local-adapter-fun-asr-nano:recognize_samples_with_params,可带hotwords、language。local-adapter-qwen3-chat:complete复用上一次请求的 KV 前缀;complete_after把给定文本预填为助手回复的开头再续写(例如重译时保留已稳定的译文)。local-adapter-silero-vad:逐窗语音概率与 VAD 迭代器。
GPU 与 ONNX Runtime
-
使用官方 ONNX Runtime 1.31.0,运行时动态加载(ort
load-dynamic),编译时不需要它。Docker 镜像已内置:CPU 版,以及 GPU 版的 CUDA 12 构建(CUDA 12.8 + cuDNN 镜像)。 -
源码构建(Rust 1.92+):GPU 版必须加
--features cuda,否则所有模型都在 CPU 上运行;再用fetch_onnxruntime把校验过 SHA-256 的 ONNX Runtime 放到二进制旁边:cargo build --release --bins --features cuda # CPU 版去掉 --features cuda python -m scripts.local.fetch_onnxruntime # CPU 版加 --cpu -
worker 优先加载
ORT_DYLIB_PATH,否则加载二进制旁的 ONNX Runtime。Windows 上需要在 PATH 中提供 CUDA 12.8+ 运行时(cudart、cuBLAS)与 cuDNN 9,且不要让它加载C:\Windows\System32\onnxruntime.dll。 -
/health只说明服务在运行;模型实际使用的 provider 见 worker 日志lazy loading model。
文档
- 部署指南
- API
- 模型配置:每个分类的获取、导出、参数与调用
- 深入:实时语音协议 · 内容审核 · Qwen3-TTS 导出 · IndexTTS 延迟测试 · 实现说明
- 开发:AGENTS.md(约束、测试命令)
许可证
代码采用 MIT。各模型沿用其上游许可证,见对应模型文档。
致谢
模型来源、固定版本与许可证见各模型文档,确切的文件、revision 与 SHA-256 以 configs/providers 为准(local-registry 的测试检查每个 Hugging Face 文件都固定到 commit、每个 URL 文件都带 SHA-256 与大小)。本项目移植或参考了以下上游项目:
- modelcontextprotocol/rust-sdk:标准 MCP Rust SDK
- microsoft/onnxruntime、pykeio/ort:CPU / CUDA 推理运行时及其 Rust 绑定
- microsoft/onnxruntime-genai:Qwen3、Qwen3Guard 的 INT4 导出(
models.builder) - modelscope/FunASR、FunAudioLLM/SenseVoice:SenseVoice 前处理、推理与 FSMN-VAD 管线
- QwenAudio/Fun-ASR:Fun-ASR-Nano 的模型结构、提示词与推理流程
- ultralytics/ultralytics:YOLO 预处理、输出解码与 COCO 标签
- PaddlePaddle/PaddleOCR:PP-OCRv5、DB 检测后处理与 CTC 解码
- baidu/Unlimited-OCR:预处理、提示词、R-SWA 与防重复采样
- index-tts/index-tts、DakeQQ/Text-to-Speech-TTS-ONNX:IndexTTS 及其 ONNX 导出与推理
- QwenLM/Qwen3-TTS:Qwen3-TTS(
qwen-tts),导出与校验的参考 - PaddlePaddle/PaddleSpeech、wetext-rs(wetext)、jieba-rs:中文 TTS 前端(见实现说明)
- snakers4/silero-vad:实时语音的 VAD
- k2-fsa/sherpa-onnx、k2-fsa/icefall:唤醒词模型、关键词检测(流式 zipformer2、关键词加分束搜索、ContextGraph)与训练配方
- DepthAnything/Depth-Anything-V2:米制深度