> **ä½ å’Œæˆ‘ï¼Œå’±ä»¬æ¥èŠèŠä¸€ä»¶æŒºé…·çš„事儿。**
>
> æƒ³è±¡ä¸€ä¸‹ï¼Œä½ è¾›è¾›è‹¦è‹¦ç”¨ Python è®ç»ƒå¥½äº†ä¸€ä¸ªè¶…级厉害的 AI 模型,它能读懂人心ã€èƒ½å†™è¯—ã€èƒ½åˆ†è¾¨ä¸€å¥è¯æ˜¯å¤¸ä½ è¿˜æ˜¯éª‚ä½ ã€‚ç„¶åŽä½ çš„è€æ¿è¯´ï¼š"ä¸é”™ä¸é”™ï¼ŒçŽ°åœ¨æŠŠå®ƒéƒ¨ç½²åˆ°æˆ‘ä»¬å…¬å¸çš„ Go åŽç«¯é‡ŒåŽ»ã€‚"
>
> ä½ æ„£åœ¨é‚£é‡Œï¼Œå°±åƒä¸€åªçªç„¶è¢«é—®åˆ°å¾®ç§¯åˆ†çš„金毛犬。
>
> Python å’Œ Go,这俩就åƒä¸åŒæ˜Ÿçƒçš„è¯è¨€ã€‚怎么办?é‡å†™ï¼Ÿå†™ REST API ä¸é—´å±‚?还是用 gRPC åƒä¼ 纸æ¡ä¸€æ ·æ¥å›žä¼ æ•°æ®ï¼Ÿ
>
> 今天,我è¦ç»™ä½ 介ç»ä¸€ä¸ªç¥žå¥‡çš„æ¡¥æ¢â€”—**Hugot**。它让 Go 也能跑 Hugging Face çš„ Transformer 模型,就åƒç»™ Go 装上了 AI 的翅膀。
---
## ðŸŽ ç¬¬ä¸€ç« ï¼šå½“ Go é‡ä¸Šå˜å½¢é‡‘刚
### 1.1 问题从哪儿æ¥ï¼Ÿ
咱们先说说背景故事。
Go 是一门很棒的è¯è¨€â€”—简å•ã€é«˜æ•ˆã€å¹¶å‘能力强,特别适åˆå†™åŽç«¯æœåŠ¡ã€‚ä½†è¯´åˆ°æœºå™¨å¦ä¹ ,Go 生æ€ä¸€ç›´æœ‰ç‚¹"跛脚"。Python 那边有 PyTorchã€TensorFlowã€Hugging Face Transformers,简直是个çƒé—¹çš„èœå¸‚场;Go 这边呢?冷冷清清。
**ä½ å¯èƒ½ä¼šé—®**:为啥ä¸ç›´æŽ¥ç”¨ Python 写æœåŠ¡ï¼Ÿ
好问题ï¼ä½†çŽ°å®žä¸æœ‰å¾ˆå¤šåŽŸå› è®©ä½ ä¸æƒ³è¿™ä¹ˆåšï¼š
- **æ•°æ®éšç§**:有些数æ®ä¸èƒ½å‡ºå…¬å¸é˜²ç«å¢™ï¼Œè°ƒç”¨ OpenAI API?门儿没有。
- **æˆæœ¬æŽ§åˆ¶**:云æœåŠ¡æŒ‰ token 收费,é‡å¤§äº†è‚‰ç–¼ã€‚
- **å»¶è¿Ÿè¦æ±‚**:REST API 调用å†å¿«ä¹Ÿæœ‰ç½‘络开销,本地推ç†å¿«å¾—多。
- **æŠ€æœ¯æ ˆç»Ÿä¸€**:团队全是 Go å¼€å‘è€…ï¼Œä¸æƒ³ç»´æŠ¤ä¸€å¥— Python æœåŠ¡ã€‚
> **å°è´´å£«**:Transformer 是 2017 å¹´ Google æå‡ºçš„一ç§ç¥žç»ç½‘ç»œæž¶æž„ï¼ŒçŽ°åœ¨å‡ ä¹Žæ‰€æœ‰çš„å¤§è¯è¨€æ¨¡åž‹ï¼ˆåƒ GPTã€BERTï¼‰éƒ½æ˜¯åŸºäºŽå®ƒã€‚ä½ å¯ä»¥æŠŠå®ƒæƒ³è±¡æˆä¸€ç§"超级注æ„力机制"ï¼Œè®©æ¨¡åž‹èƒ½åŒæ—¶å…³æ³¨å¥å里的所有è¯ï¼Œè€Œä¸æ˜¯åƒä»¥å‰çš„æ¨¡åž‹é‚£æ ·ä¸€ä¸ªè¯ä¸€ä¸ªè¯åœ°çœ‹ã€‚
### 1.2 Hugot 是什么?
**Hugot**(读作 /huËÉ¡oÊŠ/,对,就是雨果那个å‘音)是 Knights Analytics 团队开æºçš„一个 Go åº“ã€‚å®ƒçš„ç›®æ ‡å¾ˆç®€å•:**è®©ä½ åœ¨ Go 里åƒç”¨ Python ä¸€æ ·æ–¹ä¾¿åœ°è·‘ Hugging Face çš„ Transformer 模型**。
å®ƒçš„è®¾è®¡å“²å¦æœ‰ä¸‰æ¡ï¼š
1. **å¿ å®žè¿˜åŽŸ**:尽é‡è·Ÿ Python 版 Hugging Face çš„è¡¨çŽ°ä¸€è‡´ï¼Œä½ åœ¨ Python 里测试好的模型,放到 Go é‡Œåº”è¯¥è·‘å‡ºä¸€æ ·çš„ç»“æžœã€‚
2. **生产就绪**:专注 ONNX æ ¼å¼çš„æ¨¡åž‹ï¼ˆåŽé¢ä¼šè§£é‡Šè¿™æ˜¯ä»€ä¹ˆï¼‰ï¼Œè¿½æ±‚性能和稳定性。
3. **本地化部署**:ä¸ç”¨ä¾èµ–外部 APIï¼Œæ¨¡åž‹è·‘åœ¨ä½ è‡ªå·±çš„æœºå™¨ä¸Šã€‚
> **å°è´´å£«**:ONNX(Open Neural Network Exchange)是微软主导的一ç§å¼€æ”¾å¼ç¥žç»ç½‘ç»œäº¤æ¢æ ¼å¼ã€‚ä½ å¯ä»¥æŠŠå®ƒæƒ³è±¡æˆ"模型的 PDF"——ä¸ç®¡ç”¨ä»€ä¹ˆå·¥å…·è®ç»ƒå‡ºæ¥çš„æ¨¡åž‹ï¼Œè½¬æ¢æˆ ONNX åŽï¼Œéƒ½èƒ½åœ¨å„ç§æŽ¨ç†å¼•擎上跑。Hugot 底层用的是 ONNX Runtime,这是一个高度优化的推ç†å¼•擎。
### 1.3 架构一瞥
Hugot 的架构其实挺简æ´çš„:
```
┌─────────────────────────────────────────────────────────â”
│ ä½ çš„ Go 应用 │
├─────────────────────────────────────────────────────────┤
│ Hugot Library (pipelines) │
│ ├── FeatureExtractionPipeline │
│ ├── TextClassificationPipeline │
│ ├── TokenClassificationPipeline │
│ ├── ZeroShotClassificationPipeline │
│ ├── TextGenerationPipeline │
│ ├── CrossEncoderPipeline │
│ └── ImageClassificationPipeline │
├─────────────────────────────────────────────────────────┤
│ ONNX Runtime Go Bindings │
├─────────────────────────────────────────────────────────┤
│ Native Libraries │
│ ├── libtokenizers.a (Rust, 文本分è¯) │
│ └── libonnxruntime.so (C++, 模型推ç†) │
└─────────────────────────────────────────────────────────┘
```
**关键组件**:
- **Tokenizers**ï¼šè´Ÿè´£æŠŠæ–‡æœ¬åˆ‡æˆæ¨¡åž‹èƒ½ç†è§£çš„"å°ç‰‡ç‰‡"(tokens)。Hugot 用的是一个 Rust 写的分è¯å™¨ï¼Œé€šè¿‡ C 绑定桥接到 Go。
- **ONNX Runtime**:负责实际跑神ç»ç½‘络。这是微软的项目,ç»è¿‡å¤šå¹´æ‰“磨,性能相当好。
- **Pipelines**:Hugot çš„é«˜çº§æŠ½è±¡ï¼Œè®©ä½ ä¸ç”¨å…³å¿ƒåº•å±‚ç»†èŠ‚ï¼Œå‡ è¡Œä»£ç 就能跑模型。
---
## 🚀 ç¬¬äºŒç« ï¼šæèµ·ä½ 的工作å°
### 2.1 安装å‰ä½ 需è¦ä»€ä¹ˆï¼Ÿ
Hugot ç›®å‰ä¸»è¦åœ¨ **Linux AMD64** 上测试过。想在其他平å°è·‘?ç†è®ºä¸Šå¯è¡Œï¼Œä½†å¯èƒ½è¦è¸©ä¸€äº›å‘。
ä½ éœ€è¦å‡†å¤‡ä¸¤æ ·ä¸œè¥¿ï¼š
1. **libtokenizers.a**:Rust 写的分è¯å™¨é™æ€åº“
2. **libonnxruntime.so**:ONNX Runtime 动æ€åº“
#### 安装 Tokenizers
å¦‚æžœä½ è£…äº† Rust:
```bash
git clone https://github.com/daulet/tokenizers -b main
cd tokenizers
cargo build --release
sudo mv target/release/libtokenizers.a /usr/lib/libtokenizers.a
```
或者,直接从 Hugot çš„ Release 页é¢ä¸‹è½½é¢„编译的 `libtokenizers.a`。
#### 安装 ONNX Runtime
```bash
# å‡è®¾ä½ è¦å®‰è£… 1.17.3 版本
export ONNXRUNTIME_VERSION=1.17.3
curl -LO https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}.tgz
tar -xzf onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}.tgz
sudo mv ./onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}/lib/libonnxruntime.so.${ONNXRUNTIME_VERSION} /usr/lib/onnxruntime.so
```
> **å°è´´å£«**ï¼šå¦‚æžœä½ ç”¨ GPU(NVIDIA CUDA),需è¦ä¸‹è½½ `onnxruntime-gpu` 版本,并确ä¿ä½ çš„ CUDA å’Œ cuDNN 版本匹é…。比如 ONNX Runtime 1.17.3 éœ€è¦ CUDA 12.x å’Œ cuDNN 8.9.2.26。
### 2.2 Go 模å—åˆå§‹åŒ–
```bash
mkdir my-hugot-app
cd my-hugot-app
go mod init my-hugot-app
go get github.com/knights-analytics/hugot
```
### 2.3 验è¯å®‰è£…
先写个简å•çš„ç¨‹åºæµ‹è¯•一下:
```go
package main
import (
"fmt"
"github.com/knights-analytics/hugot"
)
func main() {
// 创建 Session,会自动寻找 /usr/lib/onnxruntime.so
session, err := hugot.NewSession()
if err != nil {
panic(fmt.Sprintf("创建 session 失败: %v", err))
}
defer session.Destroy()
fmt.Println("🎉 Hugot 安装æˆåŠŸï¼")
}
```
è¿è¡Œï¼š
```bash
go run main.go
```
如果看到"Hugot 安装æˆåŠŸï¼",æå–œä½ ,å¯ä»¥å¼€å§‹çŽ©è€äº†ã€‚
### 2.4 CLI 工具安装(å¯é€‰ï¼‰
Hugot 还æä¾›äº†ä¸€ä¸ªå‘½ä»¤è¡Œå·¥å…·ï¼Œä¸ç”¨å†™ä»£ç 也能跑模型:
```bash
curl https://raw.githubusercontent.com/knights-analytics/hugot/main/scripts/install-hugot-cli.sh | bash
```
这会安装 `hugot` 二进制到 `~/.local/bin`,并带上需è¦çš„库文件。
---
## 🧩 ç¬¬ä¸‰ç« ï¼šç†è§£ Hugot çš„æ ¸å¿ƒæ¦‚å¿µ
### 3.1 Session:一切的开始
在 Hugot 里,**Session** æ˜¯ä½ çš„"工作间"。它管ç†ç€ ONNX Runtime 的环境,所有的 Pipeline 都è¦ä¾é™„于一个 Session 创建。
```go
// 基础创建方å¼
session, err := hugot.NewSession()
// 如果 onnxruntime.so ä¸åœ¨é»˜è®¤ä½ç½®
session, err := hugot.NewSession(hugot.WithOnnxLibraryPath("/path/to/onnxruntime.so"))
```
**é‡è¦**:Session 创建æˆåŠŸåŽï¼Œç”¨å®Œä¸€å®šè¦è°ƒç”¨ `session.Destroy()` 清ç†èµ„æºï¼Œå¦åˆ™ä¼šæœ‰å†…å˜æ³„æ¼ã€‚
> **å°è´´å£«**:Session å°±åƒä½ 在工厂里的工ä½ã€‚ä½ åœ¨è¿™ä¸ªå·¥ä½ä¸Šå¯ä»¥æŽ¥å¤šä¸ªæ´»ï¼ˆåˆ›å»ºå¤šä¸ª Pipelineï¼‰ï¼Œä½†å·¥åŽ‚èµ„æºæ˜¯æœ‰é™çš„(内å˜ã€GPU),所以下ç了è¦è®°å¾—清ç†è‡ªå·±çš„å·¥ä½ã€‚
### 3.2 Pipeline:任务的å°è£…
Pipeline 是 Hugot çš„æ ¸å¿ƒæŠ½è±¡ã€‚æ¯ä¸ª Pipeline å¯¹åº”ä¸€ç§ ML 任务类型。
ç›®å‰ Hugot 支æŒè¿™äº› Pipeline:
| Pipeline | 用途 | 典型模型 |
|---------|------|---------|
| `FeatureExtraction` | æå–文本的å‘é‡è¡¨ç¤ºï¼ˆEmbeddings) | `all-MiniLM-L6-v2`, `nomic-embed-text-v1.5` |
| `TextClassification` | 文本分类(情感分æžç‰ï¼‰ | `distilbert-base-uncased-finetuned-sst-2-english` |
| `TokenClassification` | è¯çº§åˆ«åˆ†ç±»ï¼ˆå‘½å实体识别 NER) | `distilbert-NER` |
| `ZeroShotClassification` | é›¶æ ·æœ¬åˆ†ç±»ï¼ˆä¸ç”¨è®ç»ƒå°±èƒ½åˆ†ç±»ï¼‰ | `protectai/deberta-v3-base-zeroshot-v1` |
| `TextGeneration` | 文本生æˆï¼ˆå¯¹è¯ã€ç»å†™ï¼‰ | `gpt2`, `llama` ç‰ |
| `CrossEncoder` | 交å‰ç¼–ç å™¨ï¼ˆé‡æŽ’åºã€ç›¸ä¼¼åº¦ï¼‰ | `cross-encoder/ms-marco-MiniLM-L-6-v2` |
| `ImageClassification` | 图åƒåˆ†ç±» | `resnet`, `vit` ç‰ |
æ¯ä¸ª Pipeline 都需è¦ä¸€ä¸ª Config æ¥åˆ›å»ºï¼ŒConfig 里最é‡è¦çš„æ˜¯ `ModelPath`(模型路径)。
### 3.3 模型从哪儿æ¥ï¼Ÿ
Hugot åªæ”¯æŒ ONNX æ ¼å¼çš„æ¨¡åž‹ã€‚ä½ æœ‰å‡ ç§é€‰æ‹©ï¼š
**选项 1:直接下载别人转好的 ONNX 模型**
Hugging Face 上有很多已ç»è½¬å¥½çš„ ONNX 模型,比如:
- `KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english`
- `KnightsAnalytics/all-MiniLM-L6-v2-onnx`
**选项 2:自己用 Hugging Face Optimum 转æ¢**
å¦‚æžœä½ çš„æ¨¡åž‹åªæœ‰ PyTorch æ ¼å¼ï¼ˆ`.bin` 或 `.safetensors`),å¯ä»¥ç”¨ Optimum 转æ¢ï¼š
```bash
pip install optimum[onnx]
optimum-cli export onnx --model bert-base-uncased ./bert_onnx/
```
**选项 3:让 Hugot å¸®ä½ ä¸‹è½½**
```go
modelPath, err := session.DownloadModel(
"KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english",
"./models",
hugot.NewDownloadOptions(),
)
```
> **å°è´´å£«**:Hugging Face Optimum 是 Hugging Face 官方推出的工具,专门用æ¥ä¼˜åŒ–å’Œè½¬æ¢æ¨¡åž‹ã€‚ä½ å¯ä»¥æŠŠå®ƒæƒ³è±¡æˆ"æ¨¡åž‹æ ¼å¼è½¬æ¢å™¨",能把 PyTorch æ¨¡åž‹è½¬æˆ ONNXã€TensorRT ç‰å„ç§æ ¼å¼ã€‚
---
## ðŸ“ ç¬¬å››ç« ï¼šå®žæˆ˜æ¼”ç»ƒâ€”â€”å„ç§ Pipeline 用法
### 4.1 æ–‡æœ¬åˆ†ç±»ï¼šåˆ¤æ–æƒ…感倾å‘
咱们从最ç»å…¸çš„任务开始——情感分æžã€‚给定一å¥è¯ï¼Œåˆ¤æ–它是æ£é¢è¿˜æ˜¯è´Ÿé¢ã€‚
```go
package main
import (
"encoding/json"
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
// 创建 Session
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
// 下载模型(如果还没下载)
modelPath, err := session.DownloadModel(
"KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english",
"./models",
hugot.NewDownloadOptions(),
)
if err != nil {
panic(err)
}
// 创建文本分类 Pipeline
config := pipelines.TextClassificationConfig{
ModelPath: modelPath,
Name: "sentimentPipeline",
}
sentimentPipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
// è¿è¡ŒæŽ¨ç†
batch := []string{
"This movie is disgustingly good!",
"The director tried too much",
"I absolutely love this product!",
"Terrible waste of money.",
}
results, err := sentimentPipeline.RunPipeline(batch)
if err != nil {
panic(err)
}
// 打å°ç»“æžœ
output, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(output))
}
```
è¿è¡Œç»“æžœå¤§æ¦‚é•¿è¿™æ ·ï¼š
```json
{
"ClassificationOutputs": [
[{"Label": "POSITIVE", "Score": 0.9998536}],
[{"Label": "NEGATIVE", "Score": 0.99752176}],
[{"Label": "POSITIVE", "Score": 0.9999123}],
[{"Label": "NEGATIVE", "Score": 0.9987654}]
]
}
```
> **å°è´´å£«**:DistilBERT 是 BERT çš„"瘦身版"ï¼Œå‚æ•°é‡åªæœ‰ BERT-base çš„ 60%,但ä¿ç•™äº† 97% çš„æ€§èƒ½ã€‚å°±åƒæŠŠä¸€è¾†è±ªåŽè½¿è½¦æ”¹æˆäº†ç´§å‡‘åž‹ï¼Œçœæ²¹ä½†è¿˜èƒ½è·‘。
### 4.2 ç‰¹å¾æå–ï¼šæŠŠæ–‡æœ¬å˜æˆå‘é‡
ç‰¹å¾æå–ï¼ˆä¹Ÿå« Embedding)是现代 NLP çš„åŸºçŸ³ã€‚å®ƒæŠŠä¸€æ®µæ–‡æœ¬å˜æˆä¸€ä¸ªé«˜ç»´å‘é‡ï¼Œè¿™æ ·è®¡ç®—机就能"ç†è§£"文本的å«ä¹‰äº†ã€‚
```go
package main
import (
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
modelPath, err := session.DownloadModel(
"KnightsAnalytics/all-MiniLM-L6-v2-onnx",
"./models",
hugot.NewDownloadOptions(),
)
if err != nil {
panic(err)
}
config := pipelines.FeatureExtractionConfig{
ModelPath: modelPath,
Name: "embeddingPipeline",
}
embeddingPipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
// æå–文本å‘é‡
texts := []string{
"The cat sits on the mat",
"A feline rests on the rug",
"The stock market crashed today",
}
results, err := embeddingPipeline.RunPipeline(texts)
if err != nil {
panic(err)
}
// æ¯ä¸ªæ–‡æœ¬å˜æˆä¸€ä¸ª 384 ç»´çš„å‘é‡
for i, text := range texts {
fmt.Printf("文本 %d: %s\n", i+1, text)
fmt.Printf("å‘é‡ç»´åº¦: %d\n", len(results.Embeddings[i][0]))
fmt.Printf("å‰5个值: %.4f, %.4f, %.4f, %.4f, %.4f\n\n",
results.Embeddings[i][0][0],
results.Embeddings[i][0][1],
results.Embeddings[i][0][2],
results.Embeddings[i][0][3],
results.Embeddings[i][0][4],
)
}
}
```
这些å‘釿œ‰ä»€ä¹ˆç”¨ï¼Ÿ**è¯ä¹‰æœç´¢**ï¼ä½ å¯ä»¥ï¼š
1. 把所有文档都转æˆå‘é‡å˜èµ·æ¥
2. 用户æé—®æ—¶ï¼ŒæŠŠé—®é¢˜ä¹Ÿè½¬æˆå‘é‡
3. 计算问题å‘é‡ä¸Žæ–‡æ¡£å‘é‡çš„相似度,找出最相关的文档
这就是 RAG(检索增强生æˆï¼‰çš„æ ¸å¿ƒåŽŸç†ã€‚
### 4.3 命å实体识别:找出专有åè¯
命å实体识别(NERï¼‰èƒ½å¸®ä½ ä»Žæ–‡æœ¬é‡Œæ‰¾å‡ºäººåã€åœ°åã€ç»„织åç‰å®žä½“。
```go
package main
import (
"encoding/json"
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
// 使用 NER 模型
modelPath := "./models/distilbert-NER" // å‡è®¾ä½ 已下载
config := pipelines.TokenClassificationConfig{
ModelPath: modelPath,
Name: "nerPipeline",
}
nerPipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
text := []string{
"Apple Inc. is planning to open a new store in Paris next year. Tim Cook announced the expansion.",
}
results, err := nerPipeline.RunPipeline(text)
if err != nil {
panic(err)
}
output, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(output))
}
```
è¾“å‡ºä¼šå‘Šè¯‰ä½ æ¯ä¸ª token 的类别:
- `B-ORG`:组织å的开头(Apple)
- `I-ORG`:组织åçš„ä¸é—´ï¼ˆInc.)
- `B-LOC`:地å的开头(Paris)
- `B-PER`:人å的开头(Tim)
- `I-PER`:人åçš„ä¸é—´ï¼ˆCook)
### 4.4 é›¶æ ·æœ¬åˆ†ç±»ï¼šä¸ç”¨è®ç»ƒçš„分类器
这是最神奇的 Pipeline ä¹‹ä¸€ã€‚ä½ ä¸éœ€è¦è®ç»ƒæ•°æ®ï¼Œåªéœ€è¦å‘Šè¯‰å®ƒæœ‰å“ªäº›ç±»åˆ«ï¼Œå®ƒå°±èƒ½è‡ªåŠ¨åˆ†ç±»ã€‚
```go
package main
import (
"encoding/json"
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
modelPath, err := session.DownloadModel(
"protectai/deberta-v3-base-zeroshot-v1-onnx",
"./models",
hugot.NewDownloadOptions(),
)
if err != nil {
panic(err)
}
config := pipelines.ZeroShotClassificationConfig{
ModelPath: modelPath,
Name: "zeroShotPipeline",
// è¿™é‡Œå®šä¹‰ä½ æƒ³åˆ†ç±»çš„ç±»åˆ«
Labels: []string{"科技", "体育", "政治", "娱ä¹"},
}
zeroShotPipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
texts := []string{
"特斯拉å‘布了新款电动汽车,ç»èˆªé‡Œç¨‹çªç ´ 1000 公里",
"æ¹–äººé˜Ÿåœ¨åŠ æ—¶èµ›ä¸é™©èƒœå‹‡å£«é˜Ÿï¼Œè©¹å§†æ–¯ç 下 40 分",
}
results, err := zeroShotPipeline.RunPipeline(texts)
if err != nil {
panic(err)
}
output, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(output))
}
```
### 4.5 文本生æˆï¼šè®© AI å¸®ä½ å†™ä½œ
这是 Hugot è¾ƒæ–°ç‰ˆæœ¬åŠ å…¥çš„åŠŸèƒ½ï¼Œå¯ä»¥ç›´æŽ¥è·‘生æˆå¼æ¨¡åž‹ã€‚
```go
package main
import (
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
config := pipelines.TextGenerationConfig{
ModelPath: "./models/gpt2-onnx", // ä½ çš„ ONNX 模型路径
Name: "generationPipeline",
// 生æˆå‚æ•°
MaxLength: 50, // 最大生æˆé•¿åº¦
Temperature: 0.8, // éšæœºæ€§ï¼Œè¶Šé«˜è¶Šåˆ›æ„
TopP: 0.95, // Nucleus sampling
RepetitionPenalty: 1.2, // é‡å¤æƒ©ç½š
}
genPipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
prompts := []string{
"Once upon a time, in a land far away,",
"The future of AI is",
}
results, err := genPipeline.RunPipeline(prompts)
if err != nil {
panic(err)
}
for i, result := range results.GeneratedTexts {
fmt.Printf("Prompt %d: %s\n", i+1, prompts[i])
fmt.Printf("Generated: %s\n\n", result)
}
}
```
### 4.6 图åƒåˆ†ç±»ï¼šç»™å›¾ç‰‡æ‰“æ ‡ç¾
Hugot 也能处ç†å›¾åƒï¼
```go
package main
import (
"fmt"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
func main() {
session, err := hugot.NewSession()
if err != nil {
panic(err)
}
defer session.Destroy()
config := pipelines.ImageClassificationConfig{
ModelPath: "./models/resnet50-onnx",
Name: "imagePipeline",
}
imagePipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
panic(err)
}
// ä¼ å…¥å›¾ç‰‡è·¯å¾„
images := []string{
"./cat.jpg",
"./dog.jpg",
}
results, err := imagePipeline.RunPipeline(images)
if err != nil {
panic(err)
}
for i, result := range results.Classifications {
fmt.Printf("图片 %d:\n", i+1)
for _, label := range result {
fmt.Printf(" - %s: %.2f%%\n", label.Label, label.Score*100)
}
}
}
```
---
## âš¡ ç¬¬äº”ç« ï¼šæ€§èƒ½ä¼˜åŒ–ä¸Žç¡¬ä»¶åŠ é€Ÿ
### 5.1 为什么需è¦ç¡¬ä»¶åŠ é€Ÿï¼Ÿ
Transformer 模型虽然强大,但计算é‡ä¹Ÿå¾ˆå¤§ã€‚一个 BERT-base 模型有 1.1 äº¿å‚æ•°ï¼Œè·‘在 CPU 上å¯èƒ½ä¸€ç§’åªèƒ½å¤„ç†å‡ åæ¡æ–‡æœ¬ã€‚
å¦‚æžœä½ è¦å¤„ç†å¤§é‡æ•°æ®ï¼Œæˆ–者è¦å®žæ—¶å“应用户请求,就需è¦ç¡¬ä»¶åŠ é€Ÿã€‚
### 5.2 Hugot 支æŒçš„åŠ é€Ÿå™¨
Hugot 通过 ONNX Runtime 支æŒå¤šç§ç¡¬ä»¶åŽç«¯ï¼š
| åŽç«¯ | å¹³å° | çŠ¶æ€ | 说明 |
|-----|------|------|------|
| CPU | æ‰€æœ‰å¹³å° | ✅ 稳定 | 默认模å¼ï¼Œæ— 需é¢å¤–é…ç½® |
| CUDA | NVIDIA GPU | ✅ 已测试 | éœ€è¦ CUDA 12.x å’Œ cuDNN |
| TensorRT | NVIDIA GPU | âš ï¸ æœªæµ‹è¯• | NVIDIA 的高性能推ç†å¼•擎 |
| DirectML | Windows | âš ï¸ æœªæµ‹è¯• | Windows 上的 GPU åŠ é€Ÿ |
| CoreML | Apple 设备 | âš ï¸ æœªæµ‹è¯• | iOS/macOS åŽŸç”ŸåŠ é€Ÿ |
| OpenVINO | Intel CPU/GPU | âš ï¸ æœªæµ‹è¯• | Intel 的推ç†å·¥å…·åŒ… |
### 5.3 å¯ç”¨ GPU åŠ é€Ÿ
è¦ä½¿ç”¨ CUDA åŠ é€Ÿï¼Œä½ éœ€è¦ï¼š
1. **NVIDIA 显å¡**(显å˜å»ºè®® 4GB+)
2. **CUDA 驱动和库**
3. **ONNX Runtime GPU 版本**
```bash
# 下载 GPU 版本的 ONNX Runtime
curl -LO https://github.com/microsoft/onnxruntime/releases/download/v1.17.3/onnxruntime-linux-x64-gpu-1.17.3.tgz
tar -xzf onnxruntime-linux-x64-gpu-1.17.3.tgz
sudo mv ./onnxruntime-linux-x64-gpu-1.17.3/lib/libonnxruntime.so.1.17.3 /usr/lib64/onnxruntime.so
```
在 Fedora/RHEL 上,安装 CUDA 库:
```bash
sudo dnf install cuda-cudart-12-4 libcublas-12-4 libcurand-12-4 libcufft-12-4
sudo dnf install libcudnn8 # 从 RHEL 仓库
```
Go 代ç 里ä¸éœ€è¦æ”¹ä»€ä¹ˆï¼ŒONNX Runtime 会自动检测并使用 GPU。
### 5.4 批处ç†ï¼šæå‡åžåé‡çš„秘诀
æ— è®ºç”¨ CPU 还是 GPU,**批处ç†**都是æå‡æ€§èƒ½çš„关键。
```go
// 低效:一æ¡ä¸€æ¡å¤„ç†
for _, text := range texts {
result, _ := pipeline.RunPipeline([]string{text})
// ...
}
// 高效:批é‡å¤„ç†
batchSize := 32
for i := 0; i < len(texts); i += batchSize {
end := i + batchSize
if end > len(texts) {
end = len(texts)
}
batch := texts[i:end]
results, _ := pipeline.RunPipeline(batch)
// ...
}
```
GPU 尤其å—益于批处ç†ï¼Œå› 为它的并行计算能力æžå¼ºã€‚批处ç†èƒ½æŠŠåžåé‡æå‡ 10 å€ç”šè‡³æ›´å¤šã€‚
### 5.5 模型é‡åŒ–:用精度æ¢é€Ÿåº¦
å¦‚æžœä½ çš„æ¨¡åž‹å¤ªå¤§ï¼Œå¯ä»¥è€ƒè™‘**é‡åŒ–**(Quantizationï¼‰ã€‚ç®€å•æ¥è¯´ï¼Œå°±æ˜¯æŠŠæ¨¡åž‹çš„傿•°ä»Ž 32 使µ®ç‚¹æ•°å˜æˆ 8 使•´æ•°ï¼Œç”šè‡³ 4 ä½ã€‚
这会让模型å˜å°ï¼ˆ4-8 å€ï¼‰ã€å˜å¿«ï¼Œä½†ç²¾åº¦ä¼šæœ‰è½»å¾®æŸå¤±ã€‚
用 Optimum åšé‡åŒ–:
```bash
optimum-cli export onnx \
--model bert-base-uncased \
--optimize O4 \
./bert_quantized/
```
> **å°è´´å£«**:é‡åŒ–å°±åƒæ˜¯æŠŠé«˜æ¸…ç…§ç‰‡åŽ‹ç¼©æˆ JPEG。质é‡ç¡®å®žä¼šä¸‹é™ä¸€ç‚¹ï¼Œä½†æ–‡ä»¶å°äº†ï¼ŒåŠ è½½å¿«äº†ï¼Œè€Œä¸”å¾ˆå¤šæ—¶å€™è‚‰çœ¼æ ¹æœ¬çœ‹ä¸å‡ºå·®åˆ«ã€‚
---
## ðŸ› ï¸ ç¬¬å…ç« ï¼šCLI 工具实战
### 6.1 安装 Hugot CLI
```bash
curl https://raw.githubusercontent.com/knights-analytics/hugot/main/scripts/install-hugot-cli.sh | bash
export PATH="$HOME/.local/bin:$PATH"
```
### 6.2 基本用法
Hugot CLI 从 stdin æˆ–æ–‡ä»¶è¯»å– JSON Lines æ ¼å¼çš„输入,æ¯è¡Œå¿…须有一个 `input` å—æ®µï¼š
```bash
# 从 stdin 读å–
echo '{"input": "This movie is great!"}' | hugot run \
--model=KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english \
--type=textClassification
# 从文件读å–
hugot run \
--model=KnightsAnalytics/distilbert-base-uncased-finetuned-sst-2-english \
--input=./input.jsonl \
--output=./results/ \
--type=textClassification
```
### 6.3 准备输入文件
创建 `input.jsonl`:
```jsonl
{"input": "The service was excellent!"}
{"input": "I waited for an hour and nobody came."}
{"input": "Food was okay, nothing special."}
{"input": "Best restaurant in town, hands down!"}
```
### 6.4 ç®¡é“æ“作
CLI 的设计éžå¸¸é€‚åˆ Unix 管é“:
```bash
# 从 CSV æå–文本,跑情感分æžï¼Œè¾“出到 JSON
cat reviews.csv | csvcut -c text | \
jq -R '{"input": .}' | \
hugot run --model=... --type=textClassification | \
jq '.output[0].Label'
```
---
## 🔧 ç¬¬ä¸ƒç« ï¼šæ¨¡åž‹è½¬æ¢ä¸Žè‡ªå®šä¹‰
### 7.1 用 Optimum è½¬æ¢ PyTorch 模型
大部分 Hugging Face 模型都是 PyTorch æ ¼å¼ã€‚è¦ç”¨äºŽ Hugot,需è¦å…ˆè½¬æˆ ONNX。
**基础转æ¢**:
```bash
pip install optimum[onnx]
# 转æ¢ä¸€ä¸ªæ¨¡åž‹
optimum-cli export onnx \
--model bert-base-uncased \
./bert_onnx/
```
**带优化的转æ¢**:
```bash
# O1: 基本优化
# O2: 扩展优化
# O3: 针对 CPU çš„æžè‡´ä¼˜åŒ–
# O4: 针对 GPU çš„æžè‡´ä¼˜åŒ–
optimum-cli export onnx \
--model bert-base-uncased \
--optimize O3 \
./bert_optimized/
```
### 7.2 处ç†ç§æœ‰çš„æˆ–自定义的模型
å¦‚æžœä½ æœ‰è‡ªå·±çš„æ¨¡åž‹ï¼š
1. 先在 Python 里用 Transformers ä¿å˜æ¨¡åž‹
2. 用 Optimum è½¬æ¢æˆ ONNX
3. 把 ONNX 文件放到 Hugot 能访问的地方
```python
# Python 端
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("your-model")
tokenizer = AutoTokenizer.from_pretrained("your-model")
model.save_pretrained("./my_model")
tokenizer.save_pretrained("./my_model")
```
```bash
# 转æ¢
optimum-cli export onnx --model ./my_model ./my_model_onnx/
```
### 7.3 Tokenizer 的兼容性
Hugot 使用 Rust 版的 Tokenizers 库,它跟 Python 版 Hugging Face Tokenizers 基本一致,但有些细节å¯èƒ½ä¸åŒã€‚
如果é‡åˆ° tokenizer 相关的问题:
1. ç¡®ä¿ `tokenizer.json` 文件在模型目录里
2. 检查 special tokens 是å¦ä¸€è‡´
3. 查看 Hugot çš„ issue 页é¢ï¼Œå¯èƒ½æœ‰å·²çŸ¥é—®é¢˜
---
## ðŸ—ï¸ ç¬¬å…«ç« ï¼šå®žæˆ˜é¡¹ç›®â€”â€”æž„å»ºè¯ä¹‰æœç´¢å¼•擎
### 8.1 项目概述
咱们æ¥åšä¸€ä¸ªå®Œæ•´çš„项目:用 Hugot 构建一个简å•çš„è¯ä¹‰æœç´¢å¼•擎。
功能:
- 索引一组文档,æå– embeddings
- 用户æé—®æ—¶ï¼Œæ‰¾åˆ°æœ€ç›¸å…³çš„æ–‡æ¡£
### 8.2 项目结构
```
semantic-search/
├── main.go
├── indexer.go # 文档索引
├── searcher.go # æœç´¢é€»è¾‘
├── models/ # å˜æ”¾ ONNX 模型
└── data/ # å˜æ”¾æ–‡æ¡£
```
### 8.3 æ ¸å¿ƒä»£ç
**indexer.go** - 文档索引器:
```go
package main
import (
"encoding/json"
"os"
"github.com/knights-analytics/hugot"
"github.com/knights-analytics/hugot/pipelines"
)
type Document struct {
ID string `json:"id"`
Content string `json:"content"`
Vector []float32 `json:"vector"`
}
type Indexer struct {
session *hugot.Session
pipeline *pipelines.FeatureExtractionPipeline
documents []Document
}
func NewIndexer(modelPath string) (*Indexer, error) {
session, err := hugot.NewSession()
if err != nil {
return nil, err
}
config := pipelines.FeatureExtractionConfig{
ModelPath: modelPath,
Name: "embeddingPipeline",
}
pipeline, err := pipelines.NewPipeline(session, config)
if err != nil {
return nil, err
}
return &Indexer{
session: session,
pipeline: pipeline,
documents: []Document{},
}, nil
}
func (idx *Indexer) AddDocument(id, content string) error {
results, err := idx.pipeline.RunPipeline([]string{content})
if err != nil {
return err
}
// 获å–第一个文本的å‘é‡ï¼ˆæ± 化åŽçš„)
vector := results.Embeddings[0][0]
idx.documents = append(idx.documents, Document{
ID: id,
Content: content,
Vector: vector,
})
return nil
}
func (idx *Indexer) SaveIndex(path string) error {
data, err := json.Marshal(idx.documents)
if err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}
func (idx *Indexer) Destroy() {
idx.session.Destroy()
}
```
**searcher.go** - æœç´¢å¼•擎:
```go
package main
import (
"encoding/json"
"math"
"os"
"sort"
)
type SearchResult struct {
Document Document
Score float64
}
type Searcher struct {
indexer *Indexer
}
func NewSearcher(indexer *Indexer) *Searcher {
return &Searcher{indexer: indexer}
}
func (s *Searcher) LoadIndex(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return err
}
return json.Unmarshal(data, &s.indexer.documents)
}
// 计算余弦相似度
func cosineSimilarity(a, b []float32) float64 {
var dotProduct, normA, normB float64
for i := 0; i < len(a); i++ {
dotProduct += float64(a[i]) * float64(b[i])
normA += float64(a[i]) * float64(a[i])
normB += float64(b[i]) * float64(b[i])
}
return dotProduct / (math.Sqrt(normA) * math.Sqrt(normB))
}
func (s *Searcher) Search(query string, topK int) ([]SearchResult, error) {
// èŽ·å–æŸ¥è¯¢çš„å‘é‡
results, err := s.indexer.pipeline.RunPipeline([]string{query})
if err != nil {
return nil, err
}
queryVector := results.Embeddings[0][0]
// 计算与所有文档的相似度
var searchResults []SearchResult
for _, doc := range s.indexer.documents {
score := cosineSimilarity(queryVector, doc.Vector)
searchResults = append(searchResults, SearchResult{
Document: doc,
Score: score,
})
}
// 排åº
sort.Slice(searchResults, func(i, j int) bool {
return searchResults[i].Score > searchResults[j].Score
})
// 返回 topK
if len(searchResults) > topK {
searchResults = searchResults[:topK]
}
return searchResults, nil
}
```
**main.go** - 使用示例:
```go
package main
import (
"fmt"
"log"
)
func main() {
// 创建索引器
indexer, err := NewIndexer("./models/all-MiniLM-L6-v2-onnx")
if err != nil {
log.Fatal(err)
}
defer indexer.Destroy()
// æ·»åŠ æ–‡æ¡£
documents := map[string]string{
"doc1": "Go is a statically typed, compiled programming language designed at Google.",
"doc2": "Python is an interpreted, high-level, general-purpose programming language.",
"doc3": "The cat sits on the mat and looks at the window.",
"doc4": "Machine learning is a subset of artificial intelligence.",
"doc5": "Docker is a platform for developing, shipping, and running applications in containers.",
}
for id, content := range documents {
if err := indexer.AddDocument(id, content); err != nil {
log.Fatal(err)
}
}
// ä¿å˜ç´¢å¼•
if err := indexer.SaveIndex("./index.json"); err != nil {
log.Fatal(err)
}
// 创建æœç´¢å™¨
searcher := NewSearcher(indexer)
searcher.LoadIndex("./index.json")
// æœç´¢
queries := []string{
"programming languages",
"containers and deployment",
"AI technology",
}
for _, query := range queries {
fmt.Printf("\n🔠Query: %s\n", query)
fmt.Println("-------------------")
results, err := searcher.Search(query, 2)
if err != nil {
log.Fatal(err)
}
for i, result := range results {
fmt.Printf("%d. [%s] Score: %.4f\n", i+1, result.Document.ID, result.Score)
fmt.Printf(" %s\n\n", result.Document.Content)
}
}
}
```
---
## 📚 第ä¹ç« :常è§é—®é¢˜ä¸Žè°ƒè¯•技巧
### 9.1 "cannot find onnxruntime.so"
**åŽŸå› **:ONNX Runtime 库ä¸åœ¨ç³»ç»Ÿè·¯å¾„里。
**解决**:
```bash
# 找到库文件ä½ç½®
sudo find / -name "libonnxruntime.so*" 2>/dev/null
# æ·»åŠ åˆ°ç³»ç»Ÿè·¯å¾„
export LD_LIBRARY_PATH=/path/to/onnxruntime/lib:$LD_LIBRARY_PATH
# 或者创建软链接
sudo ln -s /path/to/libonnxruntime.so.1.17.3 /usr/lib/libonnxruntime.so
```
### 9.2 "tokenizers.a not found"
**åŽŸå› **:Rust tokenizer 库没安装或ä¸åœ¨ `/usr/lib`。
**解决**:
```bash
# ç¡®ä¿æ–‡ä»¶å˜åœ¨
ls -la /usr/lib/libtokenizers.a
# 如果ä¸å˜åœ¨ï¼Œä»Ž Hugot release 下载或自己编译
```
### 9.3 æ¨¡åž‹åŠ è½½å¤±è´¥
**检查清å•**:
1. æ¨¡åž‹è·¯å¾„æ˜¯å¦æ£ç¡®ï¼Ÿ
2. 模型是 ONNX æ ¼å¼å—?
3. `model.onnx` å’Œ `tokenizer.json` 都在目录里å—?
4. æ¨¡åž‹æ˜¯å¦æŸå?å¯ä»¥å°è¯•釿–°ä¸‹è½½ã€‚
### 9.4 内å˜å 用过高
**解决**:
1. 使用更å°çš„æ¨¡åž‹ï¼ˆDistilBERT 替代 BERT)
2. å‡å°‘批处ç†å¤§å°
3. åŠæ—¶é”€æ¯ä¸ç”¨çš„ Pipeline å’Œ Session
4. 考虑模型é‡åŒ–
### 9.5 GPU ä¸å·¥ä½œ
**检查清å•**:
1. 安装了 GPU 版本的 ONNX Runtime å—?
2. CUDA å’Œ cuDNN 版本匹é…å—?
3. NVIDIA 驱动æ£å¸¸å—?`nvidia-smi` 能看到显å¡å—?
4. æ˜¾å¡æ˜¾å˜å¤Ÿå—?
---
## 🔮 第åç« ï¼šæœªæ¥å±•望
Hugot 是一个快速å‘展的项目,未æ¥å¯èƒ½ä¼šæœ‰è¿™äº›æ›´æ–°ï¼š
- **更多 Pipeline 类型**:问ç”ã€æ‘˜è¦ã€ç¿»è¯‘ç‰
- **è®ç»ƒæ”¯æŒ**:目å‰åªæ”¯æŒæŽ¨ç†ï¼Œæœªæ¥å¯èƒ½æ”¯æŒåœ¨ Go 里微调模型
- **更广泛的硬件支æŒ**:Apple Siliconã€Intel GPU ç‰
- **纯 Go åŽç«¯**:GoMLX 项目æ£åœ¨å¼€å‘纯 Go 的计算åŽç«¯ï¼Œæœªæ¥å¯èƒ½æ•´åˆ
---
## 📠附录:速查表
### 常用命令
```bash
# 安装 Hugot CLI
curl https://raw.githubusercontent.com/knights-analytics/hugot/main/scripts/install-hugot-cli.sh | bash
# è¿è¡Œæ–‡æœ¬åˆ†ç±»
hugot run --model=MODEL_NAME --type=textClassification --input=input.jsonl
# Optimum è½¬æ¢æ¨¡åž‹
optimum-cli export onnx --model MODEL_NAME ./output/
```
### Pipeline 类型速查
| 类型 | é…置类型 | 结果类型 |
|-----|---------|---------|
| TextClassification | `TextClassificationConfig` | `TextClassificationOutput` |
| FeatureExtraction | `FeatureExtractionConfig` | `FeatureExtractionOutput` |
| TokenClassification | `TokenClassificationConfig` | `TokenClassificationOutput` |
| ZeroShotClassification | `ZeroShotClassificationConfig` | `ZeroShotClassificationOutput` |
| TextGeneration | `TextGenerationConfig` | `TextGenerationOutput` |
| CrossEncoder | `CrossEncoderConfig` | `CrossEncoderOutput` |
| ImageClassification | `ImageClassificationConfig` | `ImageClassificationOutput` |
### 模型推è
| 任务 | æŽ¨èæ¨¡åž‹ | å¤§å° |
|-----|---------|------|
| 文本分类 | `distilbert-base-uncased-finetuned-sst-2-english` | ~250MB |
| Embeddings | `all-MiniLM-L6-v2` | ~80MB |
| NER | `distilbert-NER` | ~250MB |
| é›¶æ ·æœ¬åˆ†ç±» | `deberta-v3-base-zeroshot-v1` | ~400MB |
---
## 📖 å‚考文献
1. **Hugot GitHub 仓库** - https://github.com/knights-analytics/hugot
- 官方æºç ã€æ–‡æ¡£å’Œç¤ºä¾‹ä»£ç
2. **Knights Analytics åšå®¢: Hugot 介ç»** - https://www.knightsanalytics.com/post/hugot-llms-in-go
- 项目背景和设计哲å¦
3. **ONNX Runtime 官方文档** - https://onnxruntime.ai/
- 底层推ç†å¼•擎的详细文档
4. **Hugging Face Optimum 文档** - https://huggingface.co/docs/optimum/
- 模型转æ¢å’Œä¼˜åŒ–工具
5. **GoMLX 与 Hugot 未æ¥å±•望** - https://www.knightsanalytics.com/post/gomlx-and-hugot-expanding-the-horizons-of-machine-learning-in-go
- Go 机器å¦ä¹ 生æ€çš„å‘展方å‘
---
> **写在最åŽ**
>
> Hugot 填补了 Go 生æ€åœ¨æœºå™¨å¦ä¹ 领域的一个空白。它让我们这些喜欢用 Go 写åŽç«¯çš„人,ä¸ç”¨å†ä¸ºäº†è·‘个 AI 模型而被迫维护一套 Python æœåŠ¡ã€‚
>
> 当然,它还很年轻,功能ä¸å¦‚ Python 生æ€ä¸°å¯Œï¼Œç¡¬ä»¶æ”¯æŒä¹Ÿè¿˜æœ‰é™ã€‚但它æ£åœ¨å¿«é€Ÿè¿›æ¥ï¼Œè€Œä¸”有一个清晰的愿景:**让 Go å¼€å‘者能简å•ã€é«˜æ•ˆåœ°è¿è¡Œ Transformer 模型**。
>
> å¦‚æžœä½ çš„é¡¹ç›®éœ€è¦æœ¬åœ°éƒ¨ç½² AI èƒ½åŠ›ï¼Œæˆ–è€…ä½ æƒ³æŠŠ ML 推ç†ç›´æŽ¥é›†æˆåˆ° Go 应用里,Hugot 值得一试。
>
> 毕竟,能用一ç§è¯è¨€æžå®šçš„事,何必用两ç§å‘¢ï¼Ÿ
>
> *——å°å‡¯ï¼Œè®°äºŽ 2026 å¹´ 3 月*
#Hugot #Goè¯è¨€ #机器å¦ä¹ #HuggingFace #ONNX #教程 #è´¹æ›¼é£Žæ ¼ #å°å‡¯
登录åŽå¯å‚与表æ€
讨论回å¤
0 æ¡å›žå¤è¿˜æ²¡æœ‰äººå›žå¤ï¼Œå¿«æ¥å‘è¡¨ä½ çš„çœ‹æ³•å§ï¼
勿ƒ…链接:
AIé”æŽ§ç½‘
|
艮岳网
|
è€è–›ä¸»æœº
|
å£ç¬› - PPT智能讲解
|
æ¥å哥的åšå®¢
|
3R教室