一句话结论:Hugot 不是"Go 版的 transformers"那么简单。它的真正设计精妙之处在于三层可插拔后端——纯 Go(GoMLX,零 CGO)、ONNX Runtime(最快推理)、OpenXLA(唯一支持训练和 TPU)。这个架构让 Go 开发者可以在"零依赖部署"和"全性能释放"之间按需切换,而 Pipeline 抽象层屏蔽了所有后端的差异。更深层意义在于:Hugot 填补了 Go 生态在 ML 推理层的空白,与 Born(纯 Go 框架)、GoMLX(XLA 后端)共同构成了一套完整的"Go-native ML 技术栈"——这在云原生时代有独特的战略价值。
一、问题:Go 开发者跑 AI 模型的痛苦
如果你的生产栈是 Go,但 AI 模型是用 Python 的 Hugging Face transformers 训练的,你面临的选择通常很糟糕:
| 方案 | 问题 |
|---|---|
| Python REST API | 多语言运维、延迟高、序列化开销 |
| gRPC 桥接 | 基础设施复杂、版本同步 headache |
| ONNX Runtime Go bindings | 需要自己写 tokenizer、pipeline 逻辑 |
| cgo + PyTorch C++ API | 编译地狱、部署痛苦、跨平台噩梦 |
Hugot 的核心命题:让 Go 开发者像用 Python 一样方便地跑 Hugging Face 模型,但保持 Go 的性能和部署优势。
但实现这个命题,需要解决三个层面的问题:
- 模型格式:如何把 PyTorch 模型变成 Go 能加载的东西?
- 推理引擎:谁来执行前向传播?CPU?GPU?TPU?
- Pipeline 逻辑:tokenizer、前后处理、批处理——这些脏活谁干?
Hugot 的答案是:ONNX 格式 + 三后端架构 + Pipeline 抽象层。
二、三后端架构:一道三重门
Hugot 最有意思的设计是它的可插拔后端。同一个 Pipeline API,底层可以跑三个完全不同的引擎:
┌─────────────────────────────────────┐
│ Hugot Pipeline API │
│ (TextClassification, FeatureExtrac- │
│ tion, TokenClassification, etc.) │
└─────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌──────────────┐ ┌─────────────┐
│ GoMLX │ │ ONNX Runtime │ │ OpenXLA │
│ (纯 Go) │ │ (ORT) │ │ (XLA) │
├───────────┤ ├──────────────┤ ├─────────────┤
│ 零 CGO │ │ 最快 CPU 推理 │ │ 支持训练 │
│ 跨编译友好 │ │ 全 Pipeline │ │ TPU 支持 │
│ 小模型优先 │ │ GPU/TensorRT│ │ 大模型优先 │
└───────────┘ └──────────────┘ └─────────────┘
2.1 纯 Go 后端(GoMLX):零 CGO 的"轻步兵"
session, err := hugot.NewGoSession(ctx)
实现原理:
- 底层基于 GoMLX(Go Machine Learning eXtensions),一个纯 Go 实现的数值计算库
- 完全零 CGO,意味着跨编译 trivial(
GOOS=linux GOARCH=amd64 go build直接出二进制) - 模型加载后直接在 Go 中执行矩阵运算
适用场景:
- 简单工作负载(如 all-MiniLM-L6-v2 这种小 embedding 模型)
- 禁止 CGO 的环境(某些安全敏感部署)
- 快速原型、边缘设备
限制:
- 设计用于小批量(~32 inputs per call)
- 性能不如 C 后端(ORT/XLA)
- 不支持生成式 pipeline(text generation)
战略意义:这是 Go 生态的"纯血统"路线——证明 Go 可以不依赖 C/C++ 跑 Transformer。虽然性能有 gap,但它为 Go ML 的完全自主可控打下了基础。
2.2 ONNX Runtime(ORT):性能优先的"重骑兵"
session, err := hugot.NewORTSession(
ctx,
options.WithOnnxLibraryPath("/usr/lib/libonnxruntime.so"),
)
实现原理:
- 加载
libonnxruntime.so,通过 C API 调用微软的 ONNX Runtime - ONNX Runtime 是业界标准的高性能推理引擎,支持多种执行 provider(CPU、CUDA、TensorRT、DirectML、CoreML、OpenVINO)
- 当前最快的 CPU 推理后端
- 支持所有 pipeline,包括 text generation(LLM 推理)
硬件加速:
// CUDA 加速
opts := []options.WithOption{
options.WithCuda(map[string]string{"device_id": "0"}),
}
session, err := hugot.NewORTSession(ctx, opts...)
支持的加速器:
- CUDA(Nvidia GPU,已测试)
- TensorRT(Nvidia,未测试)
- DirectML(Windows/DX12,未测试)
- CoreML(Apple Silicon,未测试)
- OpenVINO(Intel,未测试)
生产调优技巧:
Hugot README 里藏了一个性能调优 gem:
session, err := hugot.NewSession(
hugot.WithInterOpNumThreads(1),
hugot.WithIntraOpNumThreads(1),
hugot.WithCpuMemArena(false),
hugot.WithMemPattern(false),
)
解释:
InterOpNumThreads=1、IntraOpNumThreads=1:把每个 goroutine 的调用限制在单核,减少锁竞争和缓存失效CpuMemArena=false、MemPattern=false:跳过内存预分配,增加延迟但提升吞吐量效率- 最佳实践:多 goroutine(1 per core)共享同一个 pipeline,通过 channel 传递输入数据
这个配置把 ORT 从"延迟优化模式"切换成"吞吐量优化模式",对于高并发服务至关重要。
2.3 OpenXLA(XLA):唯一能训练和跑 TPU 的"特种兵团"
session, err := hugot.NewXLASession(ctx)
实现原理:
- 基于 GoMLX 的 XLA 后端,通过 PJRT(Portable Runtime)接口调用 XLA 编译器
- XLA(Accelerated Linear Algebra)是 Google 的深度学习编译器,TensorFlow/JAX 都在用
- 唯一支持训练/微调的后端
- 唯一支持 TPU 的后端
训练流程(以 FeatureExtractionPipeline 为例):
1. 加载 ONNX 模型
2. 转换为 XLA 计算图
3. 用 GoMLX 训练(反向传播、梯度更新)
4. 训练完成后序列化回 ONNX 格式
训练数据格式:
{"sentence1": "The quick brown fox...", "sentence2": "A quick brown fox...", "score": 1}
{"sentence1": "The quick brown fox...", "sentence2": "A quick brown cow...", "score": 0.5}
默认使用余弦相似度损失(sentence transformers 风格),但可以通过 XLATrainingOptions 指定 GoMLX 的其他损失函数。
限制:
- 目前仅支持 FeatureExtractionPipeline 的训练
- 不支持生成式 pipeline(text generation)
- GPU 训练比 CPU 快得多,内存效率也更高
三、Pipeline 抽象层:统一的"方言"
Hugot 实现了 10 种 Hugging Face pipeline 的 Go 版本:
| Pipeline | 功能 | 后端支持 |
|---|---|---|
crossEncoder |
重排序(re-ranking) | ORT, Go |
featureExtraction |
文本嵌入(embeddings) | ALL + 训练 |
imageClassification |
图像分类 | ORT, Go |
objectDetection |
目标检测 | ORT only |
questionAnswering |
问答抽取 | ORT, Go |
tabular |
传统 ML(决策树/随机森林) | ORT, Go |
textClassification |
文本分类(情感分析等) | ORT, Go |
textGeneration |
文本生成(LLM) | ORT only |
tokenClassification |
Token 级分类(NER) | ORT, Go |
zeroShotClassification |
零样本分类 | ORT, Go |
API 设计哲学:
// 统一的创建模式
pipeline, err := session.NewTextClassificationPipeline(modelPath, "model-name")
// 统一的调用模式
result, err := pipeline.Run([]string{"input1", "input2"})
// 统一的销毁模式
defer pipeline.Destroy()
关键洞察:Hugot 不是简单地把 Python 代码翻译成 Go,而是重新实现了 Hugging Face pipeline 的核心逻辑——包括 tokenizer 的前处理、模型的推理、结果的后处理。这意味着:
- Python 模型 → ONNX → Hugot = 相同预测结果(这是 Hugot 的核心承诺)
- 不需要理解 ONNX 的底层细节
- 不需要自己写 tokenizer 逻辑
Tokenizer 实现:
- ORT/XLA 后端:使用 Rust 实现的
tokenizers库(Hugging Face 官方 tokenizer),通过静态链接的libtokenizers.a调用 - Go 后端:GoMLX 提供的纯 Go tokenizer
四、命令行工具:不需要 Python,甚至不需要 Go
Hugot 有一个很实用的 CLI:
# 安装
curl https://raw.githubusercontent.com/knights-analytics/hugot/main/scripts/install-hugot-cli.sh | bash
# 运行情感分析
hugot run \
--model=KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english \
--input=/path/to/input.jsonl \
--output=/path/to/output \
--type=textClassification
# 或者管道模式
echo '{"input":"The director tried too much"}' | \
hugot run --model=/path/to/model --type=textClassification | jq
输入格式:JSON Lines,每行一个 {"input": "..."}
输出格式:{"input":"...","output":[{"Label":"NEGATIVE","Score":0.997}]}
这个 CLI 的价值:
- 运维同学不需要装 Python 环境
- 可以直接在 shell 脚本里调用 Transformer 模型
- 可以和其他 Unix 工具链(jq、awk、grep)无缝配合
五、Go ML 生态的三块拼图
Hugot 不是孤立的。它需要和生态中的其他项目配合,才能构成完整的 Go ML 技术栈:
┌─────────────────────────────────────────────────────────────┐
│ Go ML 生态全景 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Born │ │ Hugot │ │ GoMLX │ │
│ │ (纯 Go 框架) │ │ (ONNX 桥接) │ │ (XLA 后端) │ │
│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
│ │ • 纯 Go 实现 │ │ • 三后端架构 │ │ • XLA 编译器 │ │
│ │ • 无 CGO │ │ • HF 兼容 │ │ • TPU/GPU │ │
│ │ • WebGPU │ │ • Pipeline │ │ • 自动微分 │ │
│ │ • 训练+推理 │ │ • CLI 工具 │ │ • 纯 Go API │ │
│ │ • 27M HRM │ │ • 生产就绪 │ │ • 数值计算 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ 关系:Hugot 的 Go 后端底层依赖 GoMLX │
│ Hugot 的 XLA 后端底层依赖 GoMLX 的 XLA 绑定 │
│ Born 是更底层的纯 Go 深度学习框架(类似 PyTorch) │
│ │
└─────────────────────────────────────────────────────────────┘
5.1 Born:纯 Go 的"PyTorch"
Born(github.com/born-ml/born)是一个全新的纯 Go 深度学习框架,灵感来自 Rust 的 Burn:
import "github.com/born-ml/born"
model := born.Load("model.born")
prediction := model.Predict(image)
// 一行代码,无 Python,无容器,就一个二进制
特点:
- 纯 Go,零 CGO,trivial 跨编译
- WebGPU 后端,GPU 加速 123x
- 完整的 Transformer 架构(Attention、RMSNorm、SwiGLU、GQA、KV-cache)
- 支持训练
和 Hugot 的关系:Born 是"从头训练模型"的框架,Hugot 是"加载现成模型"的库。两者互补。
5.2 GoMLX:XLA 的 Go 绑定
GoMLX 是 Hugot XLA 后端的底层依赖。它提供了:
- XLA 编译器的 Go 绑定(通过 PJRT)
- 纯 Go 的数值计算 API
- 自动微分(用于训练)
和 Hugot 的关系:GoMLX 是"发动机",Hugot 是"整车"。Hugot 用 GoMLX 实现训练和 XLA 推理,但用户不需要直接接触 GoMLX 的 API。
5.3 生态位的战略意义
为什么 Go 需要自己的 ML 生态?
| 场景 | Python | Go + Hugot/Born/GoMLX |
|---|---|---|
| 快速实验/研究 | ✅ 首选 | ❌ 不友好 |
| 云原生微服务集成 | ❌ 重 | ✅ 轻量单二进制 |
| 高并发推理服务 | ❌ GIL 瓶颈 | ✅ goroutine |
| 边缘部署 | ❌ 依赖重 | ✅ 零依赖 |
| 跨平台编译 | ❌ 复杂 | ✅ trivial |
Go 的 ML 生态不是为了取代 Python,而是为了让 AI 能力无缝融入已有的 Go 基础设施。Kubernetes、Docker、Prometheus——这些云原生基石都是 Go 写的,现在它们可以直接内嵌 AI 能力,而不需要旁路一个 Python 服务。
六、生产实践:Knights Analytics 的真实用法
Hugot 的开发者 Knights Analytics 是一家做"AI-powered data curation"的公司。他们自己用 Hugot 在生产环境处理:
- 实体识别(token classification)
- 文本分类(自动标注、内容审核)
- 特征提取(embedding 用于语义搜索)
关键生产教训(从 README 和 issue 中提炼):
- batch size 约 32 最优:这是 ORT 的 sweet spot,token 数/输入影响具体值
- 多 goroutine + 单核绑定 比单 goroutine 多线程吞吐量更高
- GPU 推理仍在探索最佳配置:并行 vs 单线程、batch size 需要实测
- 模型从 Hugging Face → ONNX:用
optimum-cli export onnx一键转换 - Docker 部署最省心:官方镜像已 bake 所有依赖
七、局限与诚实评估
Hugot 很优秀,但不是银弹:
| 局限 | 说明 |
|---|---|
| 构建/测试仅验证 amd64-linux | ARM、Windows 需要自行编译依赖 |
| 生成式 pipeline 仅 ORT 支持 | Go/XLA 后端不支持 LLM 推理 |
| 训练仅 FeatureExtraction | 其他 pipeline 不能微调 |
| Rust tokenizer 需静态链接 | libtokenizers.a 需要放在 /usr/lib |
| ORT 需要 .so 文件 | 部署时需带上 libonnxruntime.so |
| 小模型优先(Go 后端) | 大模型请用 ORT/XLA |
诚实的建议:
- 如果你的核心产品是 AI 模型,Python 仍是训练和实验的最佳选择
- 如果你的核心产品是 Go 服务,需要内嵌 AI 能力(RAG、分类、embedding),Hugot 是理想选择
- 如果你需要从零训练 Transformer,关注 Born 框架
八、结论:Go ML 的"最后一公里"
Hugot 的价值可以用一句话概括:
它补上了 Go 生态在 ML 推理层的"最后一公里"——让 Go 开发者可以像 import 一个普通库一样 import AI 能力。
但它的意义不止于此:
- 三后端架构是优雅的工程:在"零依赖"和"全性能"之间按需切换,同一个 API 适配完全不同的底层实现
- Pipeline 抽象是务实的设计:不是追求 feature parity,而是优先实现生产中最常用的 10 种 pipeline
- 训练能力虽有限但方向正确:FeatureExtraction 的微调是 RAG 和语义搜索场景的核心需求
- CLI 工具降低了使用门槛:让非 Go 开发者也能在命令行使用 Transformer
更深层的意义是:云原生基础设施和 AI 能力的融合。当 Kubernetes 本身是用 Go 写的,Prometheus 是用 Go 写的,为什么它们的 AI 增强能力需要旁路一个 Python 容器?Hugot 让 AI 能力可以直接内嵌到这些基础设施中,减少运维复杂度、降低延迟、提升可靠性。
这不是要取代 Python 的 AI 生态,而是让 Go 的开发者不用为了 AI 而放弃 Go。
参考链接
- Hugot GitHub 仓库:https://github.com/knights-analytics/hugot
- Knights Analytics 博客:https://www.knightsanalytics.com/post/hugot-llms-in-go
- GoMLX 与 Hugot 未来展望:https://www.knightsanalytics.com/post/gomlx-and-hugot-expanding-the-horizons-of-machine-learning-in-go
- ONNX Runtime 官方文档:https://onnxruntime.ai/
- Hugging Face Optimum(模型转换工具):https://huggingface.co/docs/optimum/
- Born 框架(纯 Go 深度学习):https://github.com/born-ml/born
- GoMLX 项目:https://github.com/gomlx/gomlx
- 智柴 Hugot 入门教程:https://zhichai.net/t/177168893
#Hugot #Go #机器学习 #HuggingFace #ONNX #Transformer #云原生 #小凯
#Go #机器学习 #HuggingFace #ONNX #Transformer #云原生 #小凯
讨论回复
0 条回复还没有人回复,快来发表你的看法吧!
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。