
有时小模型就足够了,而且你并不总是需要 GPU。将一些“工具型”任务直接跑在 CPU 上有很多理由:有时你就是没有 GPU;或者你希望数据留在本地;又或者你只是想保持架构简单。
这就是 ONNX Runtime GenAI 的用武之地。它让你可以在想要的地方运行模型:有 GPU 就用 GPU,没有就跑 CPU,而且无需改一行代码。本文将展示它如何工作。所有示例代码都在 onnx-inference 仓库中。
从哪里开始:可移植的 ML 模型
一切始于 2017 年 9 月。行业领袖意识到 ML 工具链的碎片化正在伤害所有人,于是推出了 ONNX 作为共享标准。它的主张很简单:为模型提供一个“通用翻译器”。你可以在偏好的框架中训练,导出为通用标准,然后在各种硬件目标上高效运行该模型。
行业行动迅速。到那年年底,更多公司加入;2018 年,Microsoft 将 ONNX Runtime 开源,这是一个旨在在任何硬件上高效“运行”这些模型的引擎。2019 年,它升级为 Linux Foundation AI 项目,巩固了其作为开放标准的地位。
走向何方:可移植的 LLM
当 2023 年左右 LLM 迎来爆发时,ONNX 面临新的挑战。传统模型是无状态的:输入进入,预测输出。LLM 不一样——它们“健谈”,有记忆,会逐 token 生成文本,需要管理“KV cache”来记住对话上下文。
标准的 ONNX runtimes 并不是为这种循环而生的。
因此在 2024 年,社区发布了 onnxruntime-genai。它在核心 runtime 之外封装了 LLM 所需的专用逻辑:tokenization、generation loops、诸如 beam search 的搜索策略,以及状态管理。
快进到 2026 年,我们已经在 Hugging Face 上拥有了一个预量化 ONNX 模型库。你可以即取即用,无需训练或格式转换。
使用该库
onnxruntime-genai 的好处在于它替你处理了生成逻辑。如果用原始的 ONNX Runtime,你需要手写循环把输出 token 反馈回输入。
现在看起来是这样的:
“`python
import onnxruntime_genai as og
Load a model (this path works for CPU, GPU, or mobile automatically)
model = og.Model(‘path/to/model’)
tokenizer = og.Tokenizer(model)
Configure how you want to search
params = og.GeneratorParams(model)
params.set_search_options(max_length=256, batch_size=1)
The generation loop
generator = og.Generator(model, params)
generator.append_tokens(tokenizer.encode(prompt))
while True:
generator.generate_next_token()
if generator.is_done():
break
# Decode and print as we go
token = generator.get_next_tokens()[0]
print(tokenizer.decode(token), end='', flush=True)
“`
它在幕后做了大量工作:处理 KV cache,应用你的搜索策略(greedy、top-p 等),并将算子路由至最佳可用硬件(CUDA、CoreML 或 CPU)。
硬件、模型与量化
自 LLM 早期以来,有几件事发生了变化。处理器更快了,模型在更小规模下也具备了令人惊讶的能力。
还有就是“量化”。我们不再受限于以完整的 32 位精度运行模型。像 INT4 量化这样的技术能显著压缩权重,而对准确率的影响却出乎意料地小。
我用 onnx-inference 测试了不少模型。需要注意的是,这些小模型对结构理解不错,但并不适合知识密集型任务。
对于非常简单的任务,你可以用像 SmolLM2–135M 这样的小模型。做基础补全或分类很合适。
对于更复杂的任务,你会需要更大的模型。Qwen 3–0.6B 在参数只多几亿的情况下,能力大幅提升。
当你在 CPU 上考虑超过 5 亿参数的模型时,需要仔细权衡可接受的上下文窗口、最大生成 token 数和延迟。
构建可移植的服务端
将推理逻辑封装进一个轻量级服务端能让它通用可用。无论调用方使用什么语言,都能轻松访问。我的仓库代码提供了一个实现此目的的 FastAPI 服务。
主类是 OnnxTextGenerator,它负责处理推理逻辑:
“`python
from inference import OnnxTextGenerator
Auto-detects hardware
generator = OnnxTextGenerator()
Simple run
result = generator.generate(
prompt=”Explain quantum computing like I’m five:”,
max_new_tokens=100,
temperature=0.7
)
print(result[‘generated_text’])
“`
对于实时应用,你不可能等完整答案返回。可以改用流式生成:
python
for chunk, metadata in generator.stream_generate(
prompt="Write a haiku about Docker:",
max_new_tokens=50,
temperature=0.8
):
print(chunk, end='', flush=True)
每个函数都作为一个 FastAPI endpoint 暴露:
python
@app.post("/generate")
async def generate(request: GenerateRequest):
result = generator.generate(
prompt=request.prompt,
max_new_tokens=request.max_new_tokens,
temperature=request.temperature
)
return {
"generated_text": result["generated_text"],
"tokens_generated": result["tokens_generated"],
"finish_reason": result["finish_reason"]
}
初始化器会自动寻找最佳硬件 execution provider,以实现“开箱即用”:CUDA(NVIDIA GPU)→ CoreML(Apple Silicon)→ CPU(通用回退)。
容器化策略
对于这类小模型,一个便捷的做法是将模型“直接烘焙进镜像”。这样部署后即可用,无需等待下载。
下面是一个精简版 Dockerfile:
“`dockerfile
FROM python:3.12-slim
COPY requirements.txt .
RUN pip install -r requirements.txt
ARG MODEL_ID=onnx-community/SmolLM2-135M-Instruct-ONNX
RUN hf download ${MODEL_ID} –local-dir /app/model
COPY . /app
WORKDIR /app
CMD [“uvicorn”, “app:app”, “–host”, “0.0.0.0”, “–port”, “8080”]
“`
当加载此容器时,模型已存在于磁盘上,能够即时启动,并且在无网络环境下也能正常工作。
在 Google Cloud Run 上无服务器化
Cloud Run 非常适合部署使用小模型的应用。其空闲时可缩容至零,从而无需为闲置资源付费。由于使用的是 CPU,也无需预配 GPU 实例。
从源码部署
可以直接从源码部署。以下命令使用 Google Cloud Build 构建容器,并在一步内将其部署到 Cloud Run。
我们在此设置了几个特定参数:分配 2 个 CPU(推理是计算密集型任务)和 4Gi 内存(足以容纳小模型及其 KV 缓存)。同时将并发度设为 4,使实例能在不剧烈抖动缓存的情况下处理少量并发请求。
bash
gcloud run deploy onnx-inference
--allow-unauthenticated
--concurrency 4
--cpu 2
--labels dev-tutorial=onnx-inference
--memory 4Gi
--region us-central1
--source .
测试
部署完成后,获取新服务的 URL,并使用简单的 curl 命令进行测试。
“`bash
SERVICE_URL=$(gcloud run services describe onnx-inference
–region $REGION
–format ‘value(status.url)’)
curl -X POST “$SERVICE_URL/generate”
-H “Content-Type: application/json”
-d ‘{“prompt”: “Why is efficient AI important?”, “max_new_tokens”: 50}’
“`
故障排查
可能会遇到的一些问题:
- 缺少 genai_config.json:并非所有 Hugging Face 上的 ONNX 模型都包含 ONNX Runtime GenAI 库所需的配置文件。示例代码会在缺失时尝试推断配置,但最好使用自带该配置的模型。
- Execution providers:示例目前包含 CUDA、CoreML 和 CPU,但也可以轻松添加其他 provider,例如 TensorRT 或 OpenVINO。
- 参数调整:当提高
max_new_tokens时,KV 缓存会增大,注意力机制的计算量也会增加。需关注内存占用与延迟的变化。
总结
小模型已经取得了长足进步。借助 ONNX Runtime GenAI 和适度的量化技术,如今可以在几年前还难以想象的环境中运行能力不俗的大语言模型。
这为一类全新的应用打开了大门:完全私有的本地助手、智能边缘设备,以及几乎零维护成本的无服务器 API。
如果想进行尝试,可以在几分钟内快速开始。可以从 GitHub 上的 onnx-inference 仓库获取代码,查阅官方的 ONNX Runtime GenAI 文档了解更多细节,或浏览 Hugging Face ONNX Community 寻找合适的模型。
关注“鲸栖”小程序,掌握最新AI资讯
本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:https://www.itsolotime.com/archives/20724
