Hermes-agent

This commit is contained in:
Zakaria
2026-06-14 14:30:48 -04:00
commit dac4b88b94
5058 changed files with 1884848 additions and 0 deletions
@@ -0,0 +1,350 @@
---
title: "Huggingface Accelerate — 最简分布式训练 API"
sidebar_label: "Huggingface Accelerate"
description: "最简分布式训练 API"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Huggingface Accelerate
最简分布式训练 API。仅需 4 行代码即可为任意 PyTorch 脚本添加分布式支持。统一的 DeepSpeed/FSDP/Megatron/DDP API。自动设备放置、混合精度(FP16/BF16/FP8)。交互式配置,单条启动命令。HuggingFace 生态系统标准。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/accelerate` 安装 |
| 路径 | `optional-skills/mlops/accelerate` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `accelerate`, `torch`, `transformers` |
| 平台 | linux, macos, windows |
| 标签 | `Distributed Training`, `HuggingFace`, `Accelerate`, `DeepSpeed`, `FSDP`, `Mixed Precision`, `PyTorch`, `DDP`, `Unified API`, `Simple` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# HuggingFace Accelerate - 统一分布式训练
## 快速开始
Accelerate 将分布式训练简化为 4 行代码。
**安装**
```bash
pip install accelerate
```
**转换 PyTorch 脚本**4 行):
```python
import torch
+ from accelerate import Accelerator
+ accelerator = Accelerator()
model = torch.nn.Transformer()
optimizer = torch.optim.Adam(model.parameters())
dataloader = torch.utils.data.DataLoader(dataset)
+ model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
for batch in dataloader:
optimizer.zero_grad()
loss = model(batch)
- loss.backward()
+ accelerator.backward(loss)
optimizer.step()
```
**运行**(单条命令):
```bash
accelerate launch train.py
```
## 常见工作流
### 工作流 1:从单 GPU 到多 GPU
**原始脚本**
```python
# train.py
import torch
model = torch.nn.Linear(10, 2).to('cuda')
optimizer = torch.optim.Adam(model.parameters())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)
for epoch in range(10):
for batch in dataloader:
batch = batch.to('cuda')
optimizer.zero_grad()
loss = model(batch).mean()
loss.backward()
optimizer.step()
```
**使用 Accelerate**(新增 4 行):
```python
# train.py
import torch
from accelerate import Accelerator # +1
accelerator = Accelerator() # +2
model = torch.nn.Linear(10, 2)
optimizer = torch.optim.Adam(model.parameters())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader) # +3
for epoch in range(10):
for batch in dataloader:
# 无需 .to('cuda') — 自动处理!
optimizer.zero_grad()
loss = model(batch).mean()
accelerator.backward(loss) # +4
optimizer.step()
```
**配置**(交互式):
```bash
accelerate config
```
**问题**
- 使用哪种机器?(单/多 GPU/TPU/CPU
- 机器数量?(1
- 混合精度?(no/fp16/bf16/fp8
- DeepSpeed?(no/yes
**启动**(适用于任意配置):
```bash
# 单 GPU
accelerate launch train.py
# 多 GPU8 个 GPU
accelerate launch --multi_gpu --num_processes 8 train.py
# 多节点
accelerate launch --multi_gpu --num_processes 16 \
--num_machines 2 --machine_rank 0 \
--main_process_ip $MASTER_ADDR \
train.py
```
### 工作流 2:混合精度训练
**启用 FP16/BF16**
```python
from accelerate import Accelerator
# FP16(带梯度缩放)
accelerator = Accelerator(mixed_precision='fp16')
# BF16(无缩放,更稳定)
accelerator = Accelerator(mixed_precision='bf16')
# FP8H100+
accelerator = Accelerator(mixed_precision='fp8')
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
# 其余均自动处理!
for batch in dataloader:
with accelerator.autocast(): # 可选,已自动完成
loss = model(batch)
accelerator.backward(loss)
```
### 工作流 3DeepSpeed ZeRO 集成
**启用 DeepSpeed ZeRO-2**
```python
from accelerate import Accelerator
accelerator = Accelerator(
mixed_precision='bf16',
deepspeed_plugin={
"zero_stage": 2, # ZeRO-2
"offload_optimizer": False,
"gradient_accumulation_steps": 4
}
)
# 代码与之前完全相同!
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
```
**或通过配置**
```bash
accelerate config
# 选择:DeepSpeed → ZeRO-2
```
**deepspeed_config.json**
```json
{
"fp16": {"enabled": false},
"bf16": {"enabled": true},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {"device": "cpu"},
"allgather_bucket_size": 5e8,
"reduce_bucket_size": 5e8
}
}
```
**启动**
```bash
accelerate launch --config_file deepspeed_config.json train.py
```
### 工作流 4:FSDP(全分片数据并行)
**启用 FSDP**
```python
from accelerate import Accelerator, FullyShardedDataParallelPlugin
fsdp_plugin = FullyShardedDataParallelPlugin(
sharding_strategy="FULL_SHARD", # 等价于 ZeRO-3
auto_wrap_policy="TRANSFORMER_AUTO_WRAP",
cpu_offload=False
)
accelerator = Accelerator(
mixed_precision='bf16',
fsdp_plugin=fsdp_plugin
)
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
```
**或通过配置**
```bash
accelerate config
# 选择:FSDP → Full Shard → No CPU Offload
```
### 工作流 5:梯度累积
**累积梯度**
```python
from accelerate import Accelerator
accelerator = Accelerator(gradient_accumulation_steps=4)
model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
for batch in dataloader:
with accelerator.accumulate(model): # 自动处理累积
optimizer.zero_grad()
loss = model(batch)
accelerator.backward(loss)
optimizer.step()
```
**有效批大小**`batch_size * num_gpus * gradient_accumulation_steps`
## 与替代方案的对比
**适合使用 Accelerate 的场景**
- 需要最简单的分布式训练方式
- 需要单脚本适配任意硬件
- 使用 HuggingFace 生态系统
- 需要灵活性(DDP/DeepSpeed/FSDP/Megatron
- 需要快速原型开发
**核心优势**
- **4 行代码**:代码改动极少
- **统一 API**:同一套代码适用于 DDP、DeepSpeed、FSDP、Megatron
- **自动化**:设备放置、混合精度、分片均自动处理
- **交互式配置**:无需手动配置启动器
- **单条启动命令**:适用于所有环境
**适合使用替代方案的场景**
- **PyTorch Lightning**:需要回调机制、高层抽象
- **Ray Train**:多节点编排、超参数调优
- **DeepSpeed**:直接 API 控制、高级特性
- **原生 DDP**:最大控制权、最少抽象层
## 常见问题
**问题:设备放置错误**
不要手动移动到设备:
```python
# 错误
batch = batch.to('cuda')
# 正确
# Accelerate 在 prepare() 之后自动处理
```
**问题:梯度累积不生效**
使用上下文管理器:
```python
# 正确
with accelerator.accumulate(model):
optimizer.zero_grad()
accelerator.backward(loss)
optimizer.step()
```
**问题:分布式环境下的检查点保存**
使用 accelerator 方法:
```python
# 仅在主进程保存
if accelerator.is_main_process:
accelerator.save_state('checkpoint/')
# 在所有进程上加载
accelerator.load_state('checkpoint/')
```
**问题:FSDP 结果不一致**
确保使用相同的随机种子:
```python
from accelerate.utils import set_seed
set_seed(42)
```
## 高级主题
**Megatron 集成**:张量并行、流水线并行和序列并行的配置,请参阅 [references/megatron-integration.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/accelerate/references/megatron-integration.md)。
**自定义插件**:创建自定义分布式插件及高级配置,请参阅 [references/custom-plugins.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/accelerate/references/custom-plugins.md)。
**性能调优**:性能分析、内存优化及最佳实践,请参阅 [references/performance.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/accelerate/references/performance.md)。
## 硬件要求
- **CPU**:支持(速度较慢)
- **单 GPU**:支持
- **多 GPU**DDP(默认)、DeepSpeed 或 FSDP
- **多节点**DDP、DeepSpeed、FSDP、Megatron
- **TPU**:支持
- **Apple MPS**:支持
**启动器要求**
- **DDP**`torch.distributed.run`(内置)
- **DeepSpeed**`deepspeed`pip install deepspeed
- **FSDP**PyTorch 1.12+(内置)
- **Megatron**:需自定义配置
## 资源
- 文档:https://huggingface.co/docs/accelerate
- GitHubhttps://github.com/huggingface/accelerate
- 版本:1.11.0+
- 教程:"Accelerate your scripts"
- 示例:https://github.com/huggingface/accelerate/tree/main/examples
- 使用方:HuggingFace Transformers、TRL、PEFT 及所有 HF 库
@@ -0,0 +1,425 @@
---
title: "Chroma — 面向 AI 应用的开源 embedding 数据库"
sidebar_label: "Chroma"
description: "面向 AI 应用的开源 embedding 数据库"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Chroma
面向 AI 应用的开源 embedding(向量嵌入)数据库。存储 embedding 与元数据,执行向量搜索和全文搜索,按元数据过滤。简洁的 4 函数 API,从 notebook 到生产集群均可扩展。适用于语义搜索、RAG 应用或文档检索。最适合本地开发和开源项目。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/chroma` 安装 |
| 路径 | `optional-skills/mlops/chroma` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `chromadb`, `sentence-transformers` |
| 平台 | linux, macos, windows |
| 标签 | `RAG`, `Chroma`, `Vector Database`, `Embeddings`, `Semantic Search`, `Open Source`, `Self-Hosted`, `Document Retrieval`, `Metadata Filtering` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Chroma - 开源 Embedding 数据库
专为构建具备记忆能力的 LLM 应用而设计的 AI 原生数据库。
## 何时使用 Chroma
**适用场景:**
- 构建 RAG(检索增强生成)应用
- 需要本地/自托管向量数据库
- 希望使用开源方案(Apache 2.0)
- 在 notebook 中快速原型验证
- 对文档进行语义搜索
- 存储带元数据的 embedding
**指标**
- **24,300+ GitHub stars**
- **1,900+ forks**
- **v1.3.3**(稳定版,每周发布)
- **Apache 2.0 许可证**
**以下场景请使用替代方案**
- **Pinecone**:托管云服务,自动扩缩容
- **FAISS**:纯相似度搜索,不支持元数据
- **Weaviate**:面向生产的 ML 原生数据库
- **Qdrant**:高性能,基于 Rust
## 快速开始
### 安装
```bash
# Python
pip install chromadb
# JavaScript/TypeScript
npm install chromadb @chroma-core/default-embed
```
### 基本用法(Python
```python
import chromadb
# Create client
client = chromadb.Client()
# Create collection
collection = client.create_collection(name="my_collection")
# Add documents
collection.add(
documents=["This is document 1", "This is document 2"],
metadatas=[{"source": "doc1"}, {"source": "doc2"}],
ids=["id1", "id2"]
)
# Query
results = collection.query(
query_texts=["document about topic"],
n_results=2
)
print(results)
```
## 核心操作
### 1. 创建集合
```python
# Simple collection
collection = client.create_collection("my_docs")
# With custom embedding function
from chromadb.utils import embedding_functions
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="your-key",
model_name="text-embedding-3-small"
)
collection = client.create_collection(
name="my_docs",
embedding_function=openai_ef
)
# Get existing collection
collection = client.get_collection("my_docs")
# Delete collection
client.delete_collection("my_docs")
```
### 2. 添加文档
```python
# Add with auto-generated IDs
collection.add(
documents=["Doc 1", "Doc 2", "Doc 3"],
metadatas=[
{"source": "web", "category": "tutorial"},
{"source": "pdf", "page": 5},
{"source": "api", "timestamp": "2025-01-01"}
],
ids=["id1", "id2", "id3"]
)
# Add with custom embeddings
collection.add(
embeddings=[[0.1, 0.2, ...], [0.3, 0.4, ...]],
documents=["Doc 1", "Doc 2"],
ids=["id1", "id2"]
)
```
### 3. 查询(相似度搜索)
```python
# Basic query
results = collection.query(
query_texts=["machine learning tutorial"],
n_results=5
)
# Query with filters
results = collection.query(
query_texts=["Python programming"],
n_results=3,
where={"source": "web"}
)
# Query with metadata filters
results = collection.query(
query_texts=["advanced topics"],
where={
"$and": [
{"category": "tutorial"},
{"difficulty": {"$gte": 3}}
]
}
)
# Access results
print(results["documents"]) # List of matching documents
print(results["metadatas"]) # Metadata for each doc
print(results["distances"]) # Similarity scores
print(results["ids"]) # Document IDs
```
### 4. 获取文档
```python
# Get by IDs
docs = collection.get(
ids=["id1", "id2"]
)
# Get with filters
docs = collection.get(
where={"category": "tutorial"},
limit=10
)
# Get all documents
docs = collection.get()
```
### 5. 更新文档
```python
# Update document content
collection.update(
ids=["id1"],
documents=["Updated content"],
metadatas=[{"source": "updated"}]
)
```
### 6. 删除文档
```python
# Delete by IDs
collection.delete(ids=["id1", "id2"])
# Delete with filter
collection.delete(
where={"source": "outdated"}
)
```
## 持久化存储
```python
# Persist to disk
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.create_collection("my_docs")
collection.add(documents=["Doc 1"], ids=["id1"])
# Data persisted automatically
# Reload later with same path
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_collection("my_docs")
```
## Embedding 函数
### 默认(Sentence Transformers
```python
# Uses sentence-transformers by default
collection = client.create_collection("my_docs")
# Default model: all-MiniLM-L6-v2
```
### OpenAI
```python
from chromadb.utils import embedding_functions
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="your-key",
model_name="text-embedding-3-small"
)
collection = client.create_collection(
name="openai_docs",
embedding_function=openai_ef
)
```
### HuggingFace
```python
huggingface_ef = embedding_functions.HuggingFaceEmbeddingFunction(
api_key="your-key",
model_name="sentence-transformers/all-mpnet-base-v2"
)
collection = client.create_collection(
name="hf_docs",
embedding_function=huggingface_ef
)
```
### 自定义 embedding 函数
```python
from chromadb import Documents, EmbeddingFunction, Embeddings
class MyEmbeddingFunction(EmbeddingFunction):
def __call__(self, input: Documents) -> Embeddings:
# Your embedding logic
return embeddings
my_ef = MyEmbeddingFunction()
collection = client.create_collection(
name="custom_docs",
embedding_function=my_ef
)
```
## 元数据过滤
```python
# Exact match
results = collection.query(
query_texts=["query"],
where={"category": "tutorial"}
)
# Comparison operators
results = collection.query(
query_texts=["query"],
where={"page": {"$gt": 10}} # $gt, $gte, $lt, $lte, $ne
)
# Logical operators
results = collection.query(
query_texts=["query"],
where={
"$and": [
{"category": "tutorial"},
{"difficulty": {"$lte": 3}}
]
} # Also: $or
)
# Contains
results = collection.query(
query_texts=["query"],
where={"tags": {"$in": ["python", "ml"]}}
)
```
## LangChain 集成
```python
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
# Split documents
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)
docs = text_splitter.split_documents(documents)
# Create Chroma vector store
vectorstore = Chroma.from_documents(
documents=docs,
embedding=OpenAIEmbeddings(),
persist_directory="./chroma_db"
)
# Query
results = vectorstore.similarity_search("machine learning", k=3)
# As retriever
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
```
## LlamaIndex 集成
```python
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import VectorStoreIndex, StorageContext
import chromadb
# Initialize Chroma
db = chromadb.PersistentClient(path="./chroma_db")
collection = db.get_or_create_collection("my_collection")
# Create vector store
vector_store = ChromaVectorStore(chroma_collection=collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# Create index
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
# Query
query_engine = index.as_query_engine()
response = query_engine.query("What is machine learning?")
```
## 服务器模式
```python
# Run Chroma server
# Terminal: chroma run --path ./chroma_db --port 8000
# Connect to server
import chromadb
from chromadb.config import Settings
client = chromadb.HttpClient(
host="localhost",
port=8000,
settings=Settings(anonymized_telemetry=False)
)
# Use as normal
collection = client.get_or_create_collection("my_docs")
```
## 最佳实践
1. **使用持久化客户端** — 避免重启后数据丢失
2. **添加元数据** — 支持过滤与追踪
3. **批量操作** — 一次性添加多个文档
4. **选择合适的 embedding 模型** — 平衡速度与质量
5. **使用过滤器** — 缩小搜索范围
6. **唯一 ID** — 避免冲突
7. **定期备份** — 复制 `chroma_db` 目录
8. **监控集合大小** — 按需扩容
9. **测试 embedding 函数** — 确保质量
10. **生产环境使用服务器模式** — 更适合多用户场景
## 性能
| 操作 | 延迟 | 备注 |
|-----------|---------|-------|
| 添加 100 个文档 | ~1-3s | 含 embedding 生成 |
| 查询(top 10 | ~50-200ms | 取决于集合大小 |
| 元数据过滤 | ~10-50ms | 正确索引下速度较快 |
## 资源
- **GitHub**: https://github.com/chroma-core/chroma ⭐ 24,300+
- **文档**: https://docs.trychroma.com
- **Discord**: https://discord.gg/MMeYNTmh3x
- **版本**: 1.3.3+
- **许可证**: Apache 2.0
@@ -0,0 +1,272 @@
---
title: "Clip — OpenAI 连接视觉与语言的模型"
sidebar_label: "Clip"
description: "OpenAI 连接视觉与语言的模型"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Clip
OpenAI 连接视觉与语言的模型。支持零样本图像分类、图文匹配和跨模态检索。在 4 亿图文对上训练而成。可用于图像搜索、内容审核或视觉语言任务,无需微调。最适合通用图像理解场景。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/clip` 安装 |
| 路径 | `optional-skills/mlops/clip` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `transformers`, `torch`, `pillow` |
| 平台 | linux, macos, windows |
| 标签 | `Multimodal`, `CLIP`, `Vision-Language`, `Zero-Shot`, `Image Classification`, `OpenAI`, `Image Search`, `Cross-Modal Retrieval`, `Content Moderation` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# CLIP - 对比语言图像预训练(Contrastive Language-Image Pre-Training
OpenAI 推出的能够通过自然语言理解图像的模型。
## 何时使用 CLIP
**适用场景:**
- 零样本图像分类(无需训练数据)
- 图文相似度/匹配
- 语义图像搜索
- 内容审核(检测 NSFW、暴力内容)
- 视觉问答
- 跨模态检索(图像→文本、文本→图像)
**指标**
- **GitHub 25,300+ 星**
- 在 4 亿图文对上训练
- 零样本下在 ImageNet 上与 ResNet-50 持平
- MIT 许可证
**以下情况请使用替代方案**
- **BLIP-2**:更好的图像描述生成
- **LLaVA**:视觉语言对话
- **Segment Anything**:图像分割
## 快速开始
### 安装
```bash
pip install git+https://github.com/openai/CLIP.git
pip install torch torchvision ftfy regex tqdm
```
### 零样本分类
```python
import torch
import clip
from PIL import Image
# Load model
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
# Load image
image = preprocess(Image.open("photo.jpg")).unsqueeze(0).to(device)
# Define possible labels
text = clip.tokenize(["a dog", "a cat", "a bird", "a car"]).to(device)
# Compute similarity
with torch.no_grad():
image_features = model.encode_image(image)
text_features = model.encode_text(text)
# Cosine similarity
logits_per_image, logits_per_text = model(image, text)
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
# Print results
labels = ["a dog", "a cat", "a bird", "a car"]
for label, prob in zip(labels, probs[0]):
print(f"{label}: {prob:.2%}")
```
## 可用模型
```python
# Models (sorted by size)
models = [
"RN50", # ResNet-50
"RN101", # ResNet-101
"ViT-B/32", # Vision Transformer (recommended)
"ViT-B/16", # Better quality, slower
"ViT-L/14", # Best quality, slowest
]
model, preprocess = clip.load("ViT-B/32")
```
| 模型 | 参数量 | 速度 | 质量 |
|-------|------------|-------|---------|
| RN50 | 102M | 快 | 良好 |
| ViT-B/32 | 151M | 中等 | 更好 |
| ViT-L/14 | 428M | 慢 | 最佳 |
## 图文相似度
```python
# Compute embeddings
image_features = model.encode_image(image)
text_features = model.encode_text(text)
# Normalize
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
# Cosine similarity
similarity = (image_features @ text_features.T).item()
print(f"Similarity: {similarity:.4f}")
```
## 语义图像搜索
```python
# Index images
image_paths = ["img1.jpg", "img2.jpg", "img3.jpg"]
image_embeddings = []
for img_path in image_paths:
image = preprocess(Image.open(img_path)).unsqueeze(0).to(device)
with torch.no_grad():
embedding = model.encode_image(image)
embedding /= embedding.norm(dim=-1, keepdim=True)
image_embeddings.append(embedding)
image_embeddings = torch.cat(image_embeddings)
# Search with text query
query = "a sunset over the ocean"
text_input = clip.tokenize([query]).to(device)
with torch.no_grad():
text_embedding = model.encode_text(text_input)
text_embedding /= text_embedding.norm(dim=-1, keepdim=True)
# Find most similar images
similarities = (text_embedding @ image_embeddings.T).squeeze(0)
top_k = similarities.topk(3)
for idx, score in zip(top_k.indices, top_k.values):
print(f"{image_paths[idx]}: {score:.3f}")
```
## 内容审核
```python
# Define categories
categories = [
"safe for work",
"not safe for work",
"violent content",
"graphic content"
]
text = clip.tokenize(categories).to(device)
# Check image
with torch.no_grad():
logits_per_image, _ = model(image, text)
probs = logits_per_image.softmax(dim=-1)
# Get classification
max_idx = probs.argmax().item()
max_prob = probs[0, max_idx].item()
print(f"Category: {categories[max_idx]} ({max_prob:.2%})")
```
## 批量处理
```python
# Process multiple images
images = [preprocess(Image.open(f"img{i}.jpg")) for i in range(10)]
images = torch.stack(images).to(device)
with torch.no_grad():
image_features = model.encode_image(images)
image_features /= image_features.norm(dim=-1, keepdim=True)
# Batch text
texts = ["a dog", "a cat", "a bird"]
text_tokens = clip.tokenize(texts).to(device)
with torch.no_grad():
text_features = model.encode_text(text_tokens)
text_features /= text_features.norm(dim=-1, keepdim=True)
# Similarity matrix (10 images × 3 texts)
similarities = image_features @ text_features.T
print(similarities.shape) # (10, 3)
```
## 与向量数据库集成
```python
# Store CLIP embeddings in Chroma/FAISS
import chromadb
client = chromadb.Client()
collection = client.create_collection("image_embeddings")
# Add image embeddings
for img_path, embedding in zip(image_paths, image_embeddings):
collection.add(
embeddings=[embedding.cpu().numpy().tolist()],
metadatas=[{"path": img_path}],
ids=[img_path]
)
# Query with text
query = "a sunset"
text_embedding = model.encode_text(clip.tokenize([query]))
results = collection.query(
query_embeddings=[text_embedding.cpu().numpy().tolist()],
n_results=5
)
```
## 最佳实践
1. **大多数场景使用 ViT-B/32** — 性能与速度均衡
2. **归一化 embedding(嵌入向量)** — 余弦相似度计算必须归一化
3. **批量处理** — 效率更高
4. **缓存 embedding** — 重新计算代价较高
5. **使用描述性标签** — 零样本性能更好
6. **推荐使用 GPU** — 速度提升 1050 倍
7. **预处理图像** — 使用提供的 preprocess 函数
## 性能
| 操作 | CPU | GPU (V100) |
|-----------|-----|------------|
| 图像编码 | ~200ms | ~20ms |
| 文本编码 | ~50ms | ~5ms |
| 相似度计算 | <1ms | <1ms |
## 局限性
1. **不适合细粒度任务** — 最适合宽泛类别
2. **需要描述性文本** — 模糊标签效果差
3. **网络数据偏差** — 可能存在数据集偏差
4. **无边界框** — 仅处理整张图像
5. **空间理解有限** — 位置/计数能力较弱
## 资源
- **GitHub**: https://github.com/openai/CLIP ⭐ 25,300+
- **论文**: https://arxiv.org/abs/2103.00020
- **Colab**: https://colab.research.google.com/github/openai/clip/
- **许可证**: MIT
@@ -0,0 +1,240 @@
---
title: "Faiss — Facebook 用于高效相似性搜索和密集向量聚类的库"
sidebar_label: "Faiss"
description: "Facebook 用于高效相似性搜索和密集向量聚类的库"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Faiss
Facebook 用于高效相似性搜索和密集向量聚类的库。支持数十亿向量、GPU 加速以及多种索引类型(Flat、IVF、HNSW)。适用于快速 k-NN 搜索、大规模向量检索,或仅需纯相似性搜索而无需元数据的场景。最适合高性能应用。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/faiss` 安装 |
| 路径 | `optional-skills/mlops/faiss` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `faiss-cpu`, `faiss-gpu`, `numpy` |
| 平台 | linux, macos |
| 标签 | `RAG`, `FAISS`, `Similarity Search`, `Vector Search`, `Facebook AI`, `GPU Acceleration`, `Billion-Scale`, `K-NN`, `HNSW`, `High Performance`, `Large Scale` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# FAISS - 高效相似性搜索
Facebook AI 用于十亿级向量相似性搜索的库。
## 何时使用 FAISS
**在以下情况下使用 FAISS**
- 需要对大型向量数据集(百万/十亿级)进行快速相似性搜索
- 需要 GPU 加速
- 纯向量相似性搜索(无需元数据过滤)
- 对高吞吐量、低延迟有严格要求
- 对 embedding(嵌入向量)进行离线/批量处理
**指标**
- **GitHub 31,700+ 星**
- Meta/Facebook AI Research 出品
- **支持数十亿向量**
- **C++** 并提供 Python 绑定
**以下情况请使用替代方案**
- **Chroma/Pinecone**:需要元数据过滤
- **Weaviate**:需要完整数据库功能
- **Annoy**:更简单,功能较少
## 快速开始
### 安装
```bash
# 仅 CPU
pip install faiss-cpu
# GPU 支持
pip install faiss-gpu
```
### 基本用法
```python
import faiss
import numpy as np
# 创建示例数据(1000 个向量,128 维)
d = 128
nb = 1000
vectors = np.random.random((nb, d)).astype('float32')
# 创建索引
index = faiss.IndexFlatL2(d) # L2 距离
index.add(vectors) # 添加向量
# 搜索
k = 5 # 查找 5 个最近邻
query = np.random.random((1, d)).astype('float32')
distances, indices = index.search(query, k)
print(f"Nearest neighbors: {indices}")
print(f"Distances: {distances}")
```
## 索引类型
### 1. Flat(精确搜索)
```python
# L2(欧氏)距离
index = faiss.IndexFlatL2(d)
# 内积(归一化后等同于余弦相似度)
index = faiss.IndexFlatIP(d)
# 速度最慢,精度最高
```
### 2. IVF(倒排文件)- 快速近似搜索
```python
# 创建量化器
quantizer = faiss.IndexFlatL2(d)
# 含 100 个聚类的 IVF 索引
nlist = 100
index = faiss.IndexIVFFlat(quantizer, d, nlist)
# 在数据上训练
index.train(vectors)
# 添加向量
index.add(vectors)
# 搜索(nprobe = 搜索的聚类数)
index.nprobe = 10
distances, indices = index.search(query, k)
```
### 3. HNSW(分层小世界图)- 质量/速度最佳平衡
```python
# HNSW 索引
M = 32 # 每层连接数
index = faiss.IndexHNSWFlat(d, M)
# 无需训练
index.add(vectors)
# 搜索
distances, indices = index.search(query, k)
```
### 4. 乘积量化(Product Quantization- 内存高效
```python
# PQ 可将内存减少 16-32 倍
m = 8 # 子量化器数量
nbits = 8
index = faiss.IndexPQ(d, m, nbits)
# 训练并添加
index.train(vectors)
index.add(vectors)
```
## 保存与加载
```python
# 保存索引
faiss.write_index(index, "large.index")
# 加载索引
index = faiss.read_index("large.index")
# 继续使用
distances, indices = index.search(query, k)
```
## GPU 加速
```python
# 单 GPU
res = faiss.StandardGpuResources()
index_cpu = faiss.IndexFlatL2(d)
index_gpu = faiss.index_cpu_to_gpu(res, 0, index_cpu) # GPU 0
# 多 GPU
index_gpu = faiss.index_cpu_to_all_gpus(index_cpu)
# 比 CPU 快 10-100 倍
```
## LangChain 集成
```python
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# 创建 FAISS 向量存储
vectorstore = FAISS.from_documents(docs, OpenAIEmbeddings())
# 保存
vectorstore.save_local("faiss_index")
# 加载
vectorstore = FAISS.load_local(
"faiss_index",
OpenAIEmbeddings(),
allow_dangerous_deserialization=True
)
# 搜索
results = vectorstore.similarity_search("query", k=5)
```
## LlamaIndex 集成
```python
from llama_index.vector_stores.faiss import FaissVectorStore
import faiss
# 创建 FAISS 索引
d = 1536
faiss_index = faiss.IndexFlatL2(d)
vector_store = FaissVectorStore(faiss_index=faiss_index)
```
## 最佳实践
1. **选择合适的索引类型** — 10K 以下用 Flat10K-1M 用 IVF,追求质量用 HNSW
2. **余弦相似度需归一化** — 对归一化向量使用 IndexFlatIP
3. **大数据集使用 GPU** — 速度提升 10-100 倍
4. **保存已训练的索引** — 训练成本较高
5. **调整 nprobe/ef_search** — 平衡速度与精度
6. **监控内存使用** — 大数据集使用 PQ
7. **批量查询** — 提升 GPU 利用率
## 性能对比
| 索引类型 | 构建时间 | 搜索时间 | 内存占用 | 精度 |
|----------|----------|----------|----------|------|
| Flat | 快 | 慢 | 高 | 100% |
| IVF | 中等 | 快 | 中等 | 95-99% |
| HNSW | 慢 | 最快 | 高 | 99% |
| PQ | 中等 | 快 | 低 | 90-95% |
## 资源
- **GitHub**https://github.com/facebookresearch/faiss ⭐ 31,700+
- **Wiki**https://github.com/facebookresearch/faiss/wiki
- **许可证**MIT
@@ -0,0 +1,381 @@
---
title: "优化注意力 Flash"
sidebar_label: "优化注意力 Flash"
description: "通过 Flash Attention 优化 Transformer 注意力机制,实现 2-4 倍加速和 10-20 倍内存减少"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# 优化注意力 Flash
通过 Flash Attention 优化 Transformer 注意力机制,实现 2-4 倍加速和 10-20 倍内存减少。适用于以下场景:使用长序列(>512 token)训练/运行 Transformer、遇到注意力相关的 GPU 内存问题,或需要更快的推理速度。支持 PyTorch 原生 SDPA、flash-attn 库、H100 FP8 以及滑动窗口注意力。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/flash-attention` 安装 |
| 路径 | `optional-skills/mlops/flash-attention` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `flash-attn`, `torch`, `transformers` |
| 平台 | linux, macos |
| 标签 | `Optimization`, `Flash Attention`, `Attention Optimization`, `Memory Efficiency`, `Speed Optimization`, `Long Context`, `PyTorch`, `SDPA`, `H100`, `FP8`, `Transformers` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Flash Attention - 快速内存高效注意力
## 快速开始
Flash Attention 通过 IO 感知分块(IO-aware tiling)和重计算(recomputation)技术,为 Transformer 注意力提供 2-4 倍加速和 10-20 倍内存减少。
**PyTorch 原生方式(最简单,PyTorch 2.2+**
```python
import torch
import torch.nn.functional as F
q = torch.randn(2, 8, 512, 64, device='cuda', dtype=torch.float16) # [batch, heads, seq, dim]
k = torch.randn(2, 8, 512, 64, device='cuda', dtype=torch.float16)
v = torch.randn(2, 8, 512, 64, device='cuda', dtype=torch.float16)
# 如果可用,自动使用 Flash Attention
out = F.scaled_dot_product_attention(q, k, v)
```
**flash-attn 库(功能更多)**
```bash
pip install flash-attn --no-build-isolation
```
```python
from flash_attn import flash_attn_func
# q, k, v: [batch, seqlen, nheads, headdim]
out = flash_attn_func(q, k, v, dropout_p=0.0, causal=True)
```
## 常见工作流
### 工作流 1:在现有 PyTorch 模型中启用
复制此检查清单:
```
Flash Attention 集成:
- [ ] 步骤 1:检查 PyTorch 版本(≥2.2
- [ ] 步骤 2:启用 Flash Attention 后端
- [ ] 步骤 3:通过性能分析验证加速效果
- [ ] 步骤 4:测试精度与基线一致
```
**步骤 1:检查 PyTorch 版本**
```bash
python -c "import torch; print(torch.__version__)"
# 应为 ≥2.2.0
```
如果 <2.2,请升级:
```bash
pip install --upgrade torch
```
**步骤 2:启用 Flash Attention 后端**
替换标准注意力:
```python
# 之前(标准注意力)
attn_weights = torch.softmax(q @ k.transpose(-2, -1) / math.sqrt(d_k), dim=-1)
out = attn_weights @ v
# 之后(Flash Attention
import torch.nn.functional as F
out = F.scaled_dot_product_attention(q, k, v, attn_mask=mask)
```
强制使用 Flash Attention 后端:
```python
with torch.backends.cuda.sdp_kernel(
enable_flash=True,
enable_math=False,
enable_mem_efficient=False
):
out = F.scaled_dot_product_attention(q, k, v)
```
**步骤 3:通过性能分析验证加速效果**
```python
import torch.utils.benchmark as benchmark
def test_attention(use_flash):
q, k, v = [torch.randn(2, 8, 2048, 64, device='cuda', dtype=torch.float16) for _ in range(3)]
if use_flash:
with torch.backends.cuda.sdp_kernel(enable_flash=True):
return F.scaled_dot_product_attention(q, k, v)
else:
attn = (q @ k.transpose(-2, -1) / 8.0).softmax(dim=-1)
return attn @ v
# 基准测试
t_flash = benchmark.Timer(stmt='test_attention(True)', globals=globals())
t_standard = benchmark.Timer(stmt='test_attention(False)', globals=globals())
print(f"Flash: {t_flash.timeit(100).mean:.3f}s")
print(f"Standard: {t_standard.timeit(100).mean:.3f}s")
```
预期效果:序列长度 >512 token 时有 2-4 倍加速。
**步骤 4:测试精度与基线一致**
```python
# 比较输出
q, k, v = [torch.randn(1, 8, 512, 64, device='cuda', dtype=torch.float16) for _ in range(3)]
# Flash Attention
out_flash = F.scaled_dot_product_attention(q, k, v)
# 标准注意力
attn_weights = torch.softmax(q @ k.transpose(-2, -1) / 8.0, dim=-1)
out_standard = attn_weights @ v
# 检查差异
diff = (out_flash - out_standard).abs().max()
print(f"Max difference: {diff:.6f}")
# float16 下应 <1e-3
```
### 工作流 2:使用 flash-attn 库实现高级功能
适用于多查询注意力(multi-query attention)、滑动窗口或 H100 FP8。
复制此检查清单:
```
flash-attn 库安装:
- [ ] 步骤 1:安装 flash-attn 库
- [ ] 步骤 2:修改注意力代码
- [ ] 步骤 3:启用高级功能
- [ ] 步骤 4:基准测试性能
```
**步骤 1:安装 flash-attn 库**
```bash
# NVIDIA GPUCUDA 12.0+
pip install flash-attn --no-build-isolation
# 验证安装
python -c "from flash_attn import flash_attn_func; print('Success')"
```
**步骤 2:修改注意力代码**
```python
from flash_attn import flash_attn_func
# 输入:[batch_size, seq_len, num_heads, head_dim]
# 如需要,从 [batch, heads, seq, dim] 转置
q = q.transpose(1, 2) # [batch, seq, heads, dim]
k = k.transpose(1, 2)
v = v.transpose(1, 2)
out = flash_attn_func(
q, k, v,
dropout_p=0.1,
causal=True, # 用于自回归模型
window_size=(-1, -1), # 无滑动窗口
softmax_scale=None # 自动缩放
)
out = out.transpose(1, 2) # 转回 [batch, heads, seq, dim]
```
**步骤 3:启用高级功能**
多查询注意力(跨 head 共享 K/V):
```python
from flash_attn import flash_attn_func
# q: [batch, seq, num_q_heads, dim]
# k, v: [batch, seq, num_kv_heads, dim] # 更少的 KV head
out = flash_attn_func(q, k, v) # 自动处理 MQA
```
滑动窗口注意力(局部注意力):
```python
# 仅关注前后 256 个 token 的窗口
out = flash_attn_func(
q, k, v,
window_size=(256, 256), # (左, 右) 窗口
causal=True
)
```
**步骤 4:基准测试性能**
```python
import torch
from flash_attn import flash_attn_func
import time
q, k, v = [torch.randn(4, 4096, 32, 64, device='cuda', dtype=torch.float16) for _ in range(3)]
# 预热
for _ in range(10):
_ = flash_attn_func(q, k, v)
# 基准测试
torch.cuda.synchronize()
start = time.time()
for _ in range(100):
out = flash_attn_func(q, k, v)
torch.cuda.synchronize()
end = time.time()
print(f"Time per iteration: {(end-start)/100*1000:.2f}ms")
print(f"Memory allocated: {torch.cuda.max_memory_allocated()/1e9:.2f}GB")
```
### 工作流 3H100 FP8 优化(FlashAttention-3
在 H100 GPU 上获得最大性能。
```
FP8 设置:
- [ ] 步骤 1:确认 H100 GPU 可用
- [ ] 步骤 2:安装支持 FP8 的 flash-attn
- [ ] 步骤 3:将输入转换为 FP8
- [ ] 步骤 4:使用 FP8 注意力运行
```
**步骤 1:确认 H100 GPU**
```bash
nvidia-smi --query-gpu=name --format=csv
# 应显示 "H100" 或 "H800"
```
**步骤 2:安装支持 FP8 的 flash-attn**
```bash
pip install flash-attn --no-build-isolation
# H100 的 FP8 支持已包含在内
```
**步骤 3:将输入转换为 FP8**
```python
import torch
q = torch.randn(2, 4096, 32, 64, device='cuda', dtype=torch.float16)
k = torch.randn(2, 4096, 32, 64, device='cuda', dtype=torch.float16)
v = torch.randn(2, 4096, 32, 64, device='cuda', dtype=torch.float16)
# 转换为 float8_e4m3FP8
q_fp8 = q.to(torch.float8_e4m3fn)
k_fp8 = k.to(torch.float8_e4m3fn)
v_fp8 = v.to(torch.float8_e4m3fn)
```
**步骤 4:使用 FP8 注意力运行**
```python
from flash_attn import flash_attn_func
# FlashAttention-3 在 H100 上自动使用 FP8 内核
out = flash_attn_func(q_fp8, k_fp8, v_fp8)
# 结果:约 1.2 PFLOPS,比 FP16 快 1.5-2 倍
```
## 何时使用与替代方案
**使用 Flash Attention 的场景:**
- 使用 >512 token 的序列训练 Transformer
- 使用长上下文(>2K token)进行推理
- GPU 内存受限(标准注意力 OOM)
- 需要 2-4 倍加速且不损失精度
- 使用 PyTorch 2.2+ 或可安装 flash-attn
**改用替代方案的场景:**
- **标准注意力**:序列 &lt;256 token(开销不值得)
- **xFormers**:需要更多注意力变体(不仅仅是速度)
- **内存高效注意力**CPU 推理(Flash Attention 需要 GPU
## 常见问题
**问题:ImportError: cannot import flash_attn**
使用 no-build-isolation 标志安装:
```bash
pip install flash-attn --no-build-isolation
```
或先安装 CUDA toolkit
```bash
conda install cuda -c nvidia
pip install flash-attn --no-build-isolation
```
**问题:速度低于预期(无加速效果)**
Flash Attention 的收益随序列长度增加而提升:
- &lt;512 token:加速极小(10-20%
- 512-2K token2-3 倍加速
- >2K token3-4 倍加速
请确认序列长度是否足够。
**问题:RuntimeError: CUDA error**
验证 GPU 是否支持 Flash Attention
```python
import torch
print(torch.cuda.get_device_capability())
# 应为 ≥(7, 5),即 Turing 及以上
```
Flash Attention 要求:
- AmpereA100、A10):✅ 完全支持
- TuringT4):✅ 支持
- VoltaV100):❌ 不支持
**问题:精度下降**
检查 dtype 是否为 float16 或 bfloat16(而非 float32):
```python
q = q.to(torch.float16) # 或 torch.bfloat16
```
Flash Attention 使用 float16/bfloat16 以提升速度,不支持 float32。
## 高级主题
**与 HuggingFace Transformers 集成**:参见 [references/transformers-integration.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/flash-attention/references/transformers-integration.md),了解如何在 BERT、GPT、Llama 模型中启用 Flash Attention。
**性能基准测试**:参见 [references/benchmarks.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/flash-attention/references/benchmarks.md),查看跨 GPU 和序列长度的详细速度与内存对比。
## 硬件要求
- **GPU**NVIDIA Ampere 及以上(A100、A10、A30)或 AMD MI200 及以上
- **显存**:与标准注意力相同(Flash Attention 不增加内存占用)
- **CUDA**12.0+(最低 11.8
- **PyTorch**2.2+ 以获得原生支持
**不支持**V100Volta)、CPU 推理
## 资源
- 论文:"FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness"NeurIPS 2022
- 论文:"FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning"ICLR 2024
- 博客:https://tridao.me/blog/2024/flash3/
- GitHubhttps://github.com/Dao-AILab/flash-attention
- PyTorch 文档:https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html
@@ -0,0 +1,591 @@
---
title: "Guidance"
sidebar_label: "Guidance"
description: "使用正则表达式和语法控制 LLM 输出,保证生成有效的 JSON/XML/代码,强制结构化格式,并使用 Guidance(微软研究院的约束生成框架)构建多步骤工作流..."
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Guidance
使用正则表达式和语法控制 LLM 输出,保证生成有效的 JSON/XML/代码,强制结构化格式,并使用 Guidance(微软研究院的约束生成框架)构建多步骤工作流
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/guidance` 安装 |
| 路径 | `optional-skills/mlops/guidance` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `guidance`, `transformers` |
| 平台 | linux, macos, windows |
| 标签 | `Prompt Engineering`, `Guidance`, `Constrained Generation`, `Structured Output`, `JSON Validation`, `Grammar`, `Microsoft Research`, `Format Enforcement`, `Multi-Step Workflows` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时看到的指令内容。
:::
# Guidance:约束 LLM 生成
## 何时使用此 Skill
在以下情况下使用 Guidance
- **使用正则表达式或语法控制 LLM 输出语法**
- **保证生成有效的 JSON/XML/代码**
- **相比传统 prompting(提示词)方式降低延迟**
- **强制结构化格式**(日期、邮箱、ID 等)
- **使用 Python 风格的控制流构建多步骤工作流**
- **通过语法约束防止无效输出**
**GitHub Stars**18,000+ | **来自**:微软研究院
## 安装
```bash
# 基础安装
pip install guidance
# 指定后端
pip install guidance[transformers] # Hugging Face 模型
pip install guidance[llama_cpp] # llama.cpp 模型
```
## 快速开始
### 基础示例:结构化生成
```python
from guidance import models, gen
# 加载模型(支持 OpenAI、Transformers、llama.cpp
lm = models.OpenAI("gpt-4")
# 带约束生成
result = lm + "The capital of France is " + gen("capital", max_tokens=5)
print(result["capital"]) # "Paris"
```
### 使用 Anthropic Claude
```python
from guidance import models, gen, system, user, assistant
# 配置 Claude
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# 使用上下文管理器实现对话格式
with system():
lm += "You are a helpful assistant."
with user():
lm += "What is the capital of France?"
with assistant():
lm += gen(max_tokens=20)
```
## 核心概念
### 1. 上下文管理器
Guidance 使用 Python 风格的上下文管理器实现对话式交互。
```python
from guidance import system, user, assistant, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# 系统消息
with system():
lm += "You are a JSON generation expert."
# 用户消息
with user():
lm += "Generate a person object with name and age."
# 助手回复
with assistant():
lm += gen("response", max_tokens=100)
print(lm["response"])
```
**优势:**
- 自然的对话流程
- 清晰的角色分离
- 易于阅读和维护
### 2. 约束生成
Guidance 使用正则表达式或语法确保输出符合指定模式。
#### 正则表达式约束
```python
from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# 约束为有效邮箱格式
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# 约束为日期格式(YYYY-MM-DD
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}")
# 约束为电话号码
lm += "Phone: " + gen("phone", regex=r"\d{3}-\d{3}-\d{4}")
print(lm["email"]) # 保证为有效邮箱
print(lm["date"]) # 保证为 YYYY-MM-DD 格式
```
**工作原理:**
- 正则表达式在 token(词元)级别转换为语法
- 生成过程中过滤无效 token
- 模型只能生成符合匹配条件的输出
#### 选择约束
```python
from guidance import models, gen, select
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# 约束为特定选项
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
# 多选题选择
lm += "Best answer: " + select(
["A) Paris", "B) London", "C) Berlin", "D) Madrid"],
name="answer"
)
print(lm["sentiment"]) # 其中之一:positive、negative、neutral
print(lm["answer"]) # 其中之一:A、B、C 或 D
```
### 3. Token 修复(Token Healing
Guidance 自动"修复" prompt 与生成内容之间的 token 边界。
**问题:** 分词会产生不自然的边界。
```python
# 不使用 token 修复
prompt = "The capital of France is "
# 最后一个 token" is "
# 第一个生成的 token 可能是 " Par"(带前导空格)
# 结果:"The capital of France is Paris"(双空格!)
```
**解决方案:** Guidance 回退一个 token 并重新生成。
```python
from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# 默认启用 token 修复
lm += "The capital of France is " + gen("capital", max_tokens=5)
# 结果:"The capital of France is Paris"(间距正确)
```
**优势:**
- 自然的文本边界
- 无尴尬的间距问题
- 更好的模型性能(模型看到自然的 token 序列)
### 4. 基于语法的生成
使用上下文无关语法定义复杂结构。
```python
from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# JSON 语法(简化版)
json_grammar = """
{
"name": <gen name regex="[A-Za-z ]+" max_tokens=20>,
"age": <gen age regex="[0-9]+" max_tokens=3>,
"email": <gen email regex="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" max_tokens=50>
}
"""
# 生成有效 JSON
lm += gen("person", grammar=json_grammar)
print(lm["person"]) # 保证为有效 JSON 结构
```
**使用场景:**
- 复杂结构化输出
- 嵌套数据结构
- 编程语言语法
- 领域特定语言
### 5. Guidance 函数
使用 `@guidance` 装饰器创建可复用的生成模式。
```python
from guidance import guidance, gen, models
@guidance
def generate_person(lm):
"""生成包含姓名和年龄的人物信息。"""
lm += "Name: " + gen("name", max_tokens=20, stop="\n")
lm += "\nAge: " + gen("age", regex=r"[0-9]+", max_tokens=3)
return lm
# 使用该函数
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = generate_person(lm)
print(lm["name"])
print(lm["age"])
```
**有状态函数:**
```python
@guidance(stateless=False)
def react_agent(lm, question, tools, max_rounds=5):
"""带工具调用的 ReAct agent。"""
lm += f"Question: {question}\n\n"
for i in range(max_rounds):
# 思考
lm += f"Thought {i+1}: " + gen("thought", stop="\n")
# 动作
lm += "\nAction: " + select(list(tools.keys()), name="action")
# 执行工具
tool_result = tools[lm["action"]]()
lm += f"\nObservation: {tool_result}\n\n"
# 检查是否完成
lm += "Done? " + select(["Yes", "No"], name="done")
if lm["done"] == "Yes":
break
# 最终答案
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
return lm
```
## 后端配置
### Anthropic Claude
```python
from guidance import models
lm = models.Anthropic(
model="claude-sonnet-4-5-20250929",
api_key="your-api-key" # 或设置 ANTHROPIC_API_KEY 环境变量
)
```
### OpenAI
```python
lm = models.OpenAI(
model="gpt-4o-mini",
api_key="your-api-key" # 或设置 OPENAI_API_KEY 环境变量
)
```
### 本地模型(Transformers
```python
from guidance.models import Transformers
lm = Transformers(
"microsoft/Phi-4-mini-instruct",
device="cuda" # 或 "cpu"
)
```
### 本地模型(llama.cpp
```python
from guidance.models import LlamaCpp
lm = LlamaCpp(
model_path="/path/to/model.gguf",
n_ctx=4096,
n_gpu_layers=35
)
```
## 常用模式
### 模式 1JSON 生成
```python
from guidance import models, gen, system, user, assistant
lm = models.Anthropic("claude-sonnet-4-5-20250929")
with system():
lm += "You generate valid JSON."
with user():
lm += "Generate a user profile with name, age, and email."
with assistant():
lm += """{
"name": """ + gen("name", regex=r'"[A-Za-z ]+"', max_tokens=30) + """,
"age": """ + gen("age", regex=r"[0-9]+", max_tokens=3) + """,
"email": """ + gen("email", regex=r'"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"', max_tokens=50) + """
}"""
print(lm) # 保证为有效 JSON
```
### 模式 2:分类
```python
from guidance import models, gen, select
lm = models.Anthropic("claude-sonnet-4-5-20250929")
text = "This product is amazing! I love it."
lm += f"Text: {text}\n"
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
lm += "\nConfidence: " + gen("confidence", regex=r"[0-9]+", max_tokens=3) + "%"
print(f"Sentiment: {lm['sentiment']}")
print(f"Confidence: {lm['confidence']}%")
```
### 模式 3:多步骤推理
```python
from guidance import models, gen, guidance
@guidance
def chain_of_thought(lm, question):
"""逐步推理生成答案。"""
lm += f"Question: {question}\n\n"
# 生成多个推理步骤
for i in range(3):
lm += f"Step {i+1}: " + gen(f"step_{i+1}", stop="\n", max_tokens=100) + "\n"
# 最终答案
lm += "\nTherefore, the answer is: " + gen("answer", max_tokens=50)
return lm
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = chain_of_thought(lm, "What is 15% of 200?")
print(lm["answer"])
```
### 模式 4ReAct Agent
```python
from guidance import models, gen, select, guidance
@guidance(stateless=False)
def react_agent(lm, question):
"""带工具调用的 ReAct agent。"""
tools = {
"calculator": lambda expr: eval(expr),
"search": lambda query: f"Search results for: {query}",
}
lm += f"Question: {question}\n\n"
for round in range(5):
# 思考
lm += f"Thought: " + gen("thought", stop="\n") + "\n"
# 动作选择
lm += "Action: " + select(["calculator", "search", "answer"], name="action")
if lm["action"] == "answer":
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
break
# 动作输入
lm += "\nAction Input: " + gen("action_input", stop="\n") + "\n"
# 执行工具
if lm["action"] in tools:
result = tools[lm["action"]](lm["action_input"])
lm += f"Observation: {result}\n\n"
return lm
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = react_agent(lm, "What is 25 * 4 + 10?")
print(lm["answer"])
```
### 模式 5:数据提取
```python
from guidance import models, gen, guidance
@guidance
def extract_entities(lm, text):
"""从文本中提取结构化实体。"""
lm += f"Text: {text}\n\n"
# 提取人物
lm += "Person: " + gen("person", stop="\n", max_tokens=30) + "\n"
# 提取组织
lm += "Organization: " + gen("organization", stop="\n", max_tokens=30) + "\n"
# 提取日期
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}", max_tokens=10) + "\n"
# 提取地点
lm += "Location: " + gen("location", stop="\n", max_tokens=30) + "\n"
return lm
text = "Tim Cook announced at Apple Park on 2024-09-15 in Cupertino."
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = extract_entities(lm, text)
print(f"Person: {lm['person']}")
print(f"Organization: {lm['organization']}")
print(f"Date: {lm['date']}")
print(f"Location: {lm['location']}")
```
## 最佳实践
### 1. 使用正则表达式进行格式验证
```python
# ✅ 好:正则表达式确保格式有效
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# ❌ 差:自由生成可能产生无效邮箱
lm += "Email: " + gen("email", max_tokens=50)
```
### 2. 对固定类别使用 select()
```python
# ✅ 好:保证为有效类别
lm += "Status: " + select(["pending", "approved", "rejected"], name="status")
# ❌ 差:可能生成拼写错误或无效值
lm += "Status: " + gen("status", max_tokens=20)
```
### 3. 利用 Token 修复
```python
# 默认启用 token 修复
# 无需特殊操作——自然拼接即可
lm += "The capital is " + gen("capital") # 自动修复
```
### 4. 使用停止序列
```python
# ✅ 好:在换行处停止,适用于单行输出
lm += "Name: " + gen("name", stop="\n")
# ❌ 差:可能生成多行内容
lm += "Name: " + gen("name", max_tokens=50)
```
### 5. 创建可复用函数
```python
# ✅ 好:可复用模式
@guidance
def generate_person(lm):
lm += "Name: " + gen("name", stop="\n")
lm += "\nAge: " + gen("age", regex=r"[0-9]+")
return lm
# 多次使用
lm = generate_person(lm)
lm += "\n\n"
lm = generate_person(lm)
```
### 6. 平衡约束力度
```python
# ✅ 好:合理的约束
lm += gen("name", regex=r"[A-Za-z ]+", max_tokens=30)
# ❌ 过于严格:可能失败或非常缓慢
lm += gen("name", regex=r"^(John|Jane)$", max_tokens=10)
```
## 与替代方案的对比
| 特性 | Guidance | Instructor | Outlines | LMQL |
|---------|----------|------------|----------|------|
| 正则表达式约束 | ✅ 支持 | ❌ 不支持 | ✅ 支持 | ✅ 支持 |
| 语法支持 | ✅ CFG | ❌ 不支持 | ✅ CFG | ✅ CFG |
| Pydantic 验证 | ❌ 不支持 | ✅ 支持 | ✅ 支持 | ❌ 不支持 |
| Token 修复 | ✅ 支持 | ❌ 不支持 | ✅ 支持 | ❌ 不支持 |
| 本地模型 | ✅ 支持 | ⚠️ 有限 | ✅ 支持 | ✅ 支持 |
| API 模型 | ✅ 支持 | ✅ 支持 | ⚠️ 有限 | ✅ 支持 |
| Python 风格语法 | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ 类 SQL |
| 学习曲线 | 低 | 低 | 中 | 高 |
**何时选择 Guidance**
- 需要正则表达式/语法约束
- 需要 token 修复
- 构建带控制流的复杂工作流
- 使用本地模型(Transformers、llama.cpp
- 偏好 Python 风格语法
**何时选择替代方案:**
- Instructor:需要带自动重试的 Pydantic 验证
- Outlines:需要 JSON schema 验证
- LMQL:偏好声明式查询语法
## 性能特性
**延迟降低:**
- 对于约束输出,比传统 prompting 快 3050%
- Token 修复减少不必要的重新生成
- 语法约束防止无效 token 的生成
**内存占用:**
- 相比无约束生成,额外开销极小
- 语法编译结果在首次使用后缓存
- 推理时高效过滤 token
**Token 效率:**
- 防止在无效输出上浪费 token
- 无需重试循环
- 直接生成有效输出
## 资源
- **文档**https://guidance.readthedocs.io
- **GitHub**https://github.com/guidance-ai/guidance18k+ stars
- **Notebooks**https://github.com/guidance-ai/guidance/tree/main/notebooks
- **Discord**:提供社区支持
## 另请参阅
- `references/constraints.md` — 全面的正则表达式和语法模式
- `references/backends.md` — 后端专项配置
- `references/examples.md` — 生产就绪示例
@@ -0,0 +1,535 @@
---
title: "Huggingface Tokenizers — 为研究和生产优化的快速 tokenizer"
sidebar_label: "Huggingface Tokenizers"
description: "为研究和生产优化的快速 tokenizer"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Huggingface Tokenizers
为研究和生产优化的快速 tokenizer(分词器)。基于 Rust 的实现可在 &lt;20 秒内对 1GB 文本完成分词。支持 BPE、WordPiece 和 Unigram 算法。可训练自定义词表、追踪对齐关系、处理 padding(填充)/truncation(截断)。与 transformers 无缝集成。当需要高性能分词或训练自定义 tokenizer 时使用。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/huggingface-tokenizers` 安装 |
| 路径 | `optional-skills/mlops/huggingface-tokenizers` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `tokenizers`, `transformers`, `datasets` |
| 平台 | linux, macos, windows |
| 标签 | `Tokenization`, `HuggingFace`, `BPE`, `WordPiece`, `Unigram`, `Fast Tokenization`, `Rust`, `Custom Tokenizer`, `Alignment Tracking`, `Production` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# HuggingFace Tokenizers — 高性能 NLP 分词
具备 Rust 性能与 Python 易用性的快速、生产就绪 tokenizer。
## 何时使用 HuggingFace Tokenizers
**在以下情况下使用 HuggingFace Tokenizers**
- 需要极快的分词速度(每 GB 文本 &lt;20 秒)
- 从头训练自定义 tokenizer
- 需要对齐追踪(token → 原始文本位置)
- 构建生产级 NLP 流水线
- 需要高效地对大型语料库进行分词
**性能**
- **速度**CPU 上对 1GB 文本分词 &lt;20 秒
- **实现**Rust 核心,提供 Python/Node.js 绑定
- **效率**:比纯 Python 实现快 10100 倍
**改用其他方案的情况**
- **SentencePiece**:语言无关,被 T5/ALBERT 使用
- **tiktoken**OpenAI 用于 GPT 模型的 BPE tokenizer
- **transformers AutoTokenizer**:仅加载预训练模型时使用(内部使用本库)
## 快速开始
### 安装
```bash
# 安装 tokenizers
pip install tokenizers
# 与 transformers 集成
pip install tokenizers transformers
```
### 加载预训练 tokenizer
```python
from tokenizers import Tokenizer
# 从 HuggingFace Hub 加载
tokenizer = Tokenizer.from_pretrained("bert-base-uncased")
# 对文本编码
output = tokenizer.encode("Hello, how are you?")
print(output.tokens) # ['hello', ',', 'how', 'are', 'you', '?']
print(output.ids) # [7592, 1010, 2129, 2024, 2017, 1029]
# 解码还原
text = tokenizer.decode(output.ids)
print(text) # "hello, how are you?"
```
### 训练自定义 BPE tokenizer
```python
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import Whitespace
# 使用 BPE 模型初始化 tokenizer
tokenizer = Tokenizer(BPE(unk_token="[UNK]"))
tokenizer.pre_tokenizer = Whitespace()
# 配置训练器
trainer = BpeTrainer(
vocab_size=30000,
special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"],
min_frequency=2
)
# 在文件上训练
files = ["train.txt", "validation.txt"]
tokenizer.train(files, trainer)
# 保存
tokenizer.save("my-tokenizer.json")
```
**训练时间**100MB 语料约 12 分钟,1GB 语料约 10–20 分钟
### 批量编码与 padding
```python
# 启用 padding
tokenizer.enable_padding(pad_id=3, pad_token="[PAD]")
# 批量编码
texts = ["Hello world", "This is a longer sentence"]
encodings = tokenizer.encode_batch(texts)
for encoding in encodings:
print(encoding.ids)
# [101, 7592, 2088, 102, 3, 3, 3]
# [101, 2023, 2003, 1037, 2936, 6251, 102]
```
## 分词算法
### BPE(字节对编码)
**工作原理**
1. 从字符级词表开始
2. 找出最频繁的字符对
3. 合并为新 token,加入词表
4. 重复直到达到词表大小
**使用者**GPT-2、GPT-3、RoBERTa、BART、DeBERTa
```python
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import ByteLevel
tokenizer = Tokenizer(BPE(unk_token="<|endoftext|>"))
tokenizer.pre_tokenizer = ByteLevel()
trainer = BpeTrainer(
vocab_size=50257,
special_tokens=["<|endoftext|>"],
min_frequency=2
)
tokenizer.train(files=["data.txt"], trainer=trainer)
```
**优点**
- 能较好地处理 OOV 词(拆分为子词)
- 词表大小灵活
- 适合形态丰富的语言
**权衡**
- 分词结果依赖合并顺序
- 可能意外拆分常见词
### WordPiece
**工作原理**
1. 从字符词表开始
2. 对合并对打分:`frequency(pair) / (frequency(first) × frequency(second))`
3. 合并得分最高的对
4. 重复直到达到词表大小
**使用者**BERT、DistilBERT、MobileBERT
```python
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
from tokenizers.trainers import WordPieceTrainer
from tokenizers.pre_tokenizers import Whitespace
from tokenizers.normalizers import BertNormalizer
tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
tokenizer.normalizer = BertNormalizer(lowercase=True)
tokenizer.pre_tokenizer = Whitespace()
trainer = WordPieceTrainer(
vocab_size=30522,
special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"],
continuing_subword_prefix="##"
)
tokenizer.train(files=["corpus.txt"], trainer=trainer)
```
**优点**
- 优先进行有意义的合并(高分 = 语义相关)
- 在 BERT 中取得了最优结果
**权衡**
- 若无子词匹配,未知词变为 `[UNK]`
- 保存词表而非合并规则(文件较大)
### Unigram
**工作原理**
1. 从大词表(所有子串)开始
2. 用当前词表计算语料损失
3. 移除对损失影响最小的 token
4. 重复直到达到词表大小
**使用者**ALBERT、T5、mBART、XLNet(通过 SentencePiece
```python
from tokenizers import Tokenizer
from tokenizers.models import Unigram
from tokenizers.trainers import UnigramTrainer
tokenizer = Tokenizer(Unigram())
trainer = UnigramTrainer(
vocab_size=8000,
special_tokens=["<unk>", "<s>", "</s>"],
unk_token="<unk>"
)
tokenizer.train(files=["data.txt"], trainer=trainer)
```
**优点**
- 概率化(找到最可能的分词方式)
- 适合无词边界的语言
- 能处理多样的语言学上下文
**权衡**
- 训练计算开销较大
- 需要调整的超参数更多
## 分词流水线
完整流水线:**归一化 → 预分词 → 模型 → 后处理**
### 归一化(Normalization
清洗并标准化文本:
```python
from tokenizers.normalizers import NFD, StripAccents, Lowercase, Sequence
tokenizer.normalizer = Sequence([
NFD(), # Unicode 归一化(分解)
Lowercase(), # 转为小写
StripAccents() # 去除重音符号
])
# 输入:"Héllo WORLD"
# 归一化后:"hello world"
```
**常用归一化器**
- `NFD`, `NFC`, `NFKD`, `NFKC` — Unicode 归一化形式
- `Lowercase()` — 转为小写
- `StripAccents()` — 去除重音(é → e
- `Strip()` — 去除空白
- `Replace(pattern, content)` — 正则替换
### 预分词(Pre-tokenization
将文本拆分为类词单元:
```python
from tokenizers.pre_tokenizers import Whitespace, Punctuation, Sequence, ByteLevel
# 按空白和标点拆分
tokenizer.pre_tokenizer = Sequence([
Whitespace(),
Punctuation()
])
# 输入:"Hello, world!"
# 预分词后:["Hello", ",", "world", "!"]
```
**常用预分词器**
- `Whitespace()` — 按空格、制表符、换行符拆分
- `ByteLevel()` — GPT-2 风格的字节级拆分
- `Punctuation()` — 隔离标点
- `Digits(individual_digits=True)` — 逐个拆分数字
- `Metaspace()` — 将空格替换为 ▁(SentencePiece 风格)
### 后处理(Post-processing
为模型输入添加特殊 token
```python
from tokenizers.processors import TemplateProcessing
# BERT 风格:[CLS] sentence [SEP]
tokenizer.post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B [SEP]",
special_tokens=[
("[CLS]", 1),
("[SEP]", 2),
],
)
```
**常见模式**
```python
# GPT-2sentence <|endoftext|>
TemplateProcessing(
single="$A <|endoftext|>",
special_tokens=[("<|endoftext|>", 50256)]
)
# RoBERTa<s> sentence </s>
TemplateProcessing(
single="<s> $A </s>",
pair="<s> $A </s> </s> $B </s>",
special_tokens=[("<s>", 0), ("</s>", 2)]
)
```
## 对齐追踪
追踪 token 在原始文本中的位置:
```python
output = tokenizer.encode("Hello, world!")
# 获取 token 偏移量
for token, offset in zip(output.tokens, output.offsets):
start, end = offset
print(f"{token:10} → [{start:2}, {end:2}): {text[start:end]!r}")
# 输出:
# hello → [ 0, 5): 'Hello'
# , → [ 5, 6): ','
# world → [ 7, 12): 'world'
# ! → [12, 13): '!'
```
**使用场景**
- 命名实体识别(将预测结果映射回文本)
- 问答(提取答案片段)
- Token 分类(将标签对齐到原始位置)
## 与 transformers 集成
### 使用 AutoTokenizer 加载
```python
from transformers import AutoTokenizer
# AutoTokenizer 自动使用快速 tokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 检查是否使用快速 tokenizer
print(tokenizer.is_fast) # True
# 访问底层 tokenizers.Tokenizer
fast_tokenizer = tokenizer.backend_tokenizer
print(type(fast_tokenizer)) # <class 'tokenizers.Tokenizer'>
```
### 将自定义 tokenizer 转换为 transformers 格式
```python
from tokenizers import Tokenizer
from transformers import PreTrainedTokenizerFast
# 训练自定义 tokenizer
tokenizer = Tokenizer(BPE())
# ... 训练 tokenizer ...
tokenizer.save("my-tokenizer.json")
# 封装为 transformers 格式
transformers_tokenizer = PreTrainedTokenizerFast(
tokenizer_file="my-tokenizer.json",
unk_token="[UNK]",
pad_token="[PAD]",
cls_token="[CLS]",
sep_token="[SEP]",
mask_token="[MASK]"
)
# 像使用任何 transformers tokenizer 一样使用
outputs = transformers_tokenizer(
"Hello world",
padding=True,
truncation=True,
max_length=512,
return_tensors="pt"
)
```
## 常见模式
### 从迭代器训练(大型数据集)
```python
from datasets import load_dataset
# 加载数据集
dataset = load_dataset("wikitext", "wikitext-103-raw-v1", split="train")
# 创建批量迭代器
def batch_iterator(batch_size=1000):
for i in range(0, len(dataset), batch_size):
yield dataset[i:i + batch_size]["text"]
# 训练 tokenizer
tokenizer.train_from_iterator(
batch_iterator(),
trainer=trainer,
length=len(dataset) # 用于进度条
)
```
**性能**:约 1020 分钟处理 1GB
### 启用 truncation 和 padding
```python
# 启用 truncation
tokenizer.enable_truncation(max_length=512)
# 启用 padding
tokenizer.enable_padding(
pad_id=tokenizer.token_to_id("[PAD]"),
pad_token="[PAD]",
length=512 # 固定长度,或 None 表示批次最大长度
)
# 同时编码
output = tokenizer.encode("This is a long sentence that will be truncated...")
print(len(output.ids)) # 512
```
### 多进程处理
```python
from tokenizers import Tokenizer
from multiprocessing import Pool
# 加载 tokenizer
tokenizer = Tokenizer.from_file("tokenizer.json")
def encode_batch(texts):
return tokenizer.encode_batch(texts)
# 并行处理大型语料库
with Pool(8) as pool:
# 将语料库拆分为块
chunk_size = 1000
chunks = [corpus[i:i+chunk_size] for i in range(0, len(corpus), chunk_size)]
# 并行编码
results = pool.map(encode_batch, chunks)
```
**加速比**8 核下约 58 倍
## 性能基准
### 训练速度
| 语料大小 | BPE30k 词表) | WordPiece30k | Unigram8k |
|----------|----------------|-----------------|--------------|
| 10 MB | 15 秒 | 18 秒 | 25 秒 |
| 100 MB | 1.5 分钟 | 2 分钟 | 4 分钟 |
| 1 GB | 15 分钟 | 20 分钟 | 40 分钟 |
**硬件**16 核 CPU,在英文 Wikipedia 上测试
### 分词速度
| 实现方式 | 1 GB 语料 | 吞吐量 |
|----------------|-------------|--------------|
| 纯 Python | ~20 分钟 | ~50 MB/分钟 |
| HF Tokenizers | ~15 秒 | ~4 GB/分钟 |
| **加速比** | **80×** | **80×** |
**测试**:英文文本,平均句长 20 词
### 内存占用
| 任务 | 内存 |
|-------------------------|---------|
| 加载 tokenizer | ~10 MB |
| 训练 BPE30k 词表) | ~200 MB |
| 编码 100 万句 | ~500 MB |
## 支持的模型
可通过 `from_pretrained()` 获取的预训练 tokenizer
**BERT 系列**
- `bert-base-uncased`, `bert-large-cased`
- `distilbert-base-uncased`
- `roberta-base`, `roberta-large`
**GPT 系列**
- `gpt2`, `gpt2-medium`, `gpt2-large`
- `distilgpt2`
**T5 系列**
- `t5-small`, `t5-base`, `t5-large`
- `google/flan-t5-xxl`
**其他**
- `facebook/bart-base`, `facebook/mbart-large-cc25`
- `albert-base-v2`, `albert-xlarge-v2`
- `xlm-roberta-base`, `xlm-roberta-large`
浏览全部:https://huggingface.co/models?library=tokenizers
## 参考资料
- **[训练指南](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/huggingface-tokenizers/references/training.md)** — 训练自定义 tokenizer、配置训练器、处理大型数据集
- **[算法深度解析](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/huggingface-tokenizers/references/algorithms.md)** — BPE、WordPiece、Unigram 详细说明
- **[流水线组件](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/huggingface-tokenizers/references/pipeline.md)** — 归一化器、预分词器、后处理器、解码器
- **[Transformers 集成](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/huggingface-tokenizers/references/integration.md)** — AutoTokenizer、PreTrainedTokenizerFast、特殊 token
## 资源
- **文档**https://huggingface.co/docs/tokenizers
- **GitHub**https://github.com/huggingface/tokenizers ⭐ 9,000+
- **版本**0.20.0+
- **课程**https://huggingface.co/learn/nlp-course/chapter6/1
- **论文**BPESennrich et al., 2016)、WordPieceSchuster & Nakajima, 2012
@@ -0,0 +1,671 @@
---
title: "Outlines — Outlines:结构化 JSON/regex/Pydantic LLM 生成"
sidebar_label: "Outlines"
description: "Outlines:结构化 JSON/regex/Pydantic LLM 生成"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Outlines
Outlines:结构化 JSON/regex/Pydantic LLM 生成。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 使用 `hermes skills install official/mlops/outlines` 安装 |
| 路径 | `optional-skills/mlops/inference/outlines` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `outlines`, `transformers`, `vllm`, `pydantic` |
| 平台 | linux, macos, windows |
| 标签 | `Prompt Engineering`, `Outlines`, `Structured Generation`, `JSON Schema`, `Pydantic`, `Local Models`, `Grammar-Based Generation`, `vLLM`, `Transformers`, `Type Safety` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时看到的指令内容。
:::
# Outlines:结构化文本生成
## 何时使用此 Skill
在以下情况下使用 Outlines
- **保证有效的 JSON/XML/代码**结构化生成
- **使用 Pydantic 模型**获得类型安全的输出
- **支持本地模型**Transformers、llama.cpp、vLLM
- **通过零开销结构化生成最大化推理速度**
- **自动根据 JSON schema 生成**
- **在 grammar(语法)层面控制 token 采样**
**GitHub Stars**8,000+ | **来自**dottxt.ai(前身为 .txt
## 安装
```bash
# 基础安装
pip install outlines
# 安装特定后端
pip install outlines transformers # Hugging Face 模型
pip install outlines llama-cpp-python # llama.cpp
pip install outlines vllm # vLLM 用于高吞吐量
```
## 快速开始
### 基础示例:分类
```python
import outlines
from typing import Literal
# 加载模型
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# 带类型约束的生成
prompt = "Sentiment of 'This product is amazing!': "
generator = outlines.generate.choice(model, ["positive", "negative", "neutral"])
sentiment = generator(prompt)
print(sentiment) # "positive"(保证为其中之一)
```
### 使用 Pydantic 模型
```python
from pydantic import BaseModel
import outlines
class User(BaseModel):
name: str
age: int
email: str
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# 生成结构化输出
prompt = "Extract user: John Doe, 30 years old, john@example.com"
generator = outlines.generate.json(model, User)
user = generator(prompt)
print(user.name) # "John Doe"
print(user.age) # 30
print(user.email) # "john@example.com"
```
## 核心概念
### 1. 受约束的 Token 采样
Outlines 使用有限状态机(FSM)在 logit 层面约束 token 生成。
**工作原理:**
1. 将 schemaJSON/Pydantic/regex)转换为上下文无关文法(CFG)
2. 将 CFG 转换为有限状态机(FSM)
3. 在生成的每一步过滤无效 token
4. 当只有一个有效 token 时快速前进
**优势:**
- **零开销**:过滤在 token 层面进行
- **速度提升**:通过确定性路径快速前进
- **保证有效性**:无效输出不可能产生
```python
import outlines
# Pydantic 模型 -> JSON schema -> CFG -> FSM
class Person(BaseModel):
name: str
age: int
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# 底层流程:
# 1. Person -> JSON schema
# 2. JSON schema -> CFG
# 3. CFG -> FSM
# 4. FSM 在生成过程中过滤 token
generator = outlines.generate.json(model, Person)
result = generator("Generate person: Alice, 25")
```
### 2. 结构化生成器
Outlines 为不同输出类型提供专用生成器。
#### Choice 生成器
```python
# 多项选择
generator = outlines.generate.choice(
model,
["positive", "negative", "neutral"]
)
sentiment = generator("Review: This is great!")
# 结果:三个选项之一
```
#### JSON 生成器
```python
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
in_stock: bool
# 生成符合 schema 的有效 JSON
generator = outlines.generate.json(model, Product)
product = generator("Extract: iPhone 15, $999, available")
# 保证为有效的 Product 实例
print(type(product)) # <class '__main__.Product'>
```
#### Regex 生成器
```python
# 生成匹配 regex 的文本
generator = outlines.generate.regex(
model,
r"[0-9]{3}-[0-9]{3}-[0-9]{4}" # 电话号码模式
)
phone = generator("Generate phone number:")
# 结果:"555-123-4567"(保证匹配模式)
```
#### 整数/浮点数生成器
```python
# 生成特定数值类型
int_generator = outlines.generate.integer(model)
age = int_generator("Person's age:") # 保证为整数
float_generator = outlines.generate.float(model)
price = float_generator("Product price:") # 保证为浮点数
```
### 3. 模型后端
Outlines 支持多种本地及基于 API 的后端。
#### TransformersHugging Face
```python
import outlines
# 从 Hugging Face 加载
model = outlines.models.transformers(
"microsoft/Phi-3-mini-4k-instruct",
device="cuda" # 或 "cpu"
)
# 与任意生成器配合使用
generator = outlines.generate.json(model, YourModel)
```
#### llama.cpp
```python
# 加载 GGUF 模型
model = outlines.models.llamacpp(
"./models/llama-3.1-8b-instruct.Q4_K_M.gguf",
n_gpu_layers=35
)
generator = outlines.generate.json(model, YourModel)
```
#### vLLM(高吞吐量)
```python
# 用于生产部署
model = outlines.models.vllm(
"meta-llama/Llama-3.1-8B-Instruct",
tensor_parallel_size=2 # 多 GPU
)
generator = outlines.generate.json(model, YourModel)
```
#### OpenAI(有限支持)
```python
# 基础 OpenAI 支持
model = outlines.models.openai(
"gpt-4o-mini",
api_key="your-api-key"
)
# 注意:API 模型部分功能受限
generator = outlines.generate.json(model, YourModel)
```
### 4. Pydantic 集成
Outlines 对 Pydantic 提供一流支持,可自动进行 schema 转换。
#### 基础模型
```python
from pydantic import BaseModel, Field
class Article(BaseModel):
title: str = Field(description="Article title")
author: str = Field(description="Author name")
word_count: int = Field(description="Number of words", gt=0)
tags: list[str] = Field(description="List of tags")
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, Article)
article = generator("Generate article about AI")
print(article.title)
print(article.word_count) # 保证 > 0
```
#### 嵌套模型
```python
class Address(BaseModel):
street: str
city: str
country: str
class Person(BaseModel):
name: str
age: int
address: Address # 嵌套模型
generator = outlines.generate.json(model, Person)
person = generator("Generate person in New York")
print(person.address.city) # "New York"
```
#### Enum 与 Literal
```python
from enum import Enum
from typing import Literal
class Status(str, Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
class Application(BaseModel):
applicant: str
status: Status # 必须为枚举值之一
priority: Literal["low", "medium", "high"] # 必须为 literal 之一
generator = outlines.generate.json(model, Application)
app = generator("Generate application")
print(app.status) # Status.PENDING(或 APPROVED/REJECTED
```
## 常见模式
### 模式 1:数据提取
```python
from pydantic import BaseModel
import outlines
class CompanyInfo(BaseModel):
name: str
founded_year: int
industry: str
employees: int
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, CompanyInfo)
text = """
Apple Inc. was founded in 1976 in the technology industry.
The company employs approximately 164,000 people worldwide.
"""
prompt = f"Extract company information:\n{text}\n\nCompany:"
company = generator(prompt)
print(f"Name: {company.name}")
print(f"Founded: {company.founded_year}")
print(f"Industry: {company.industry}")
print(f"Employees: {company.employees}")
```
### 模式 2:分类
```python
from typing import Literal
import outlines
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# 二分类
generator = outlines.generate.choice(model, ["spam", "not_spam"])
result = generator("Email: Buy now! 50% off!")
# 多分类
categories = ["technology", "business", "sports", "entertainment"]
category_gen = outlines.generate.choice(model, categories)
category = category_gen("Article: Apple announces new iPhone...")
# 带置信度
class Classification(BaseModel):
label: Literal["positive", "negative", "neutral"]
confidence: float
classifier = outlines.generate.json(model, Classification)
result = classifier("Review: This product is okay, nothing special")
```
### 模式 3:结构化表单
```python
class UserProfile(BaseModel):
full_name: str
age: int
email: str
phone: str
country: str
interests: list[str]
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, UserProfile)
prompt = """
Extract user profile from:
Name: Alice Johnson
Age: 28
Email: alice@example.com
Phone: 555-0123
Country: USA
Interests: hiking, photography, cooking
"""
profile = generator(prompt)
print(profile.full_name)
print(profile.interests) # ["hiking", "photography", "cooking"]
```
### 模式 4:多实体提取
```python
class Entity(BaseModel):
name: str
type: Literal["PERSON", "ORGANIZATION", "LOCATION"]
class DocumentEntities(BaseModel):
entities: list[Entity]
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, DocumentEntities)
text = "Tim Cook met with Satya Nadella at Microsoft headquarters in Redmond."
prompt = f"Extract entities from: {text}"
result = generator(prompt)
for entity in result.entities:
print(f"{entity.name} ({entity.type})")
```
### 模式 5:代码生成
```python
class PythonFunction(BaseModel):
function_name: str
parameters: list[str]
docstring: str
body: str
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, PythonFunction)
prompt = "Generate a Python function to calculate factorial"
func = generator(prompt)
print(f"def {func.function_name}({', '.join(func.parameters)}):")
print(f' """{func.docstring}"""')
print(f" {func.body}")
```
### 模式 6:批量处理
```python
def batch_extract(texts: list[str], schema: type[BaseModel]):
"""从多段文本中提取结构化数据。"""
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, schema)
results = []
for text in texts:
result = generator(f"Extract from: {text}")
results.append(result)
return results
class Person(BaseModel):
name: str
age: int
texts = [
"John is 30 years old",
"Alice is 25 years old",
"Bob is 40 years old"
]
people = batch_extract(texts, Person)
for person in people:
print(f"{person.name}: {person.age}")
```
## 后端配置
### Transformers
```python
import outlines
# 基础用法
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# GPU 配置
model = outlines.models.transformers(
"microsoft/Phi-3-mini-4k-instruct",
device="cuda",
model_kwargs={"torch_dtype": "float16"}
)
# 常用模型
model = outlines.models.transformers("meta-llama/Llama-3.1-8B-Instruct")
model = outlines.models.transformers("mistralai/Mistral-7B-Instruct-v0.3")
model = outlines.models.transformers("Qwen/Qwen2.5-7B-Instruct")
```
### llama.cpp
```python
# 加载 GGUF 模型
model = outlines.models.llamacpp(
"./models/llama-3.1-8b.Q4_K_M.gguf",
n_ctx=4096, # 上下文窗口
n_gpu_layers=35, # GPU 层数
n_threads=8 # CPU 线程数
)
# 完全 GPU 卸载
model = outlines.models.llamacpp(
"./models/model.gguf",
n_gpu_layers=-1 # 所有层在 GPU 上
)
```
### vLLM(生产环境)
```python
# 单 GPU
model = outlines.models.vllm("meta-llama/Llama-3.1-8B-Instruct")
# 多 GPU
model = outlines.models.vllm(
"meta-llama/Llama-3.1-70B-Instruct",
tensor_parallel_size=4 # 4 块 GPU
)
# 带量化
model = outlines.models.vllm(
"meta-llama/Llama-3.1-8B-Instruct",
quantization="awq" # 或 "gptq"
)
```
## 最佳实践
### 1. 使用具体类型
```python
# ✅ 好:具体类型
class Product(BaseModel):
name: str
price: float # 非 str
quantity: int # 非 str
in_stock: bool # 非 str
# ❌ 差:全部用字符串
class Product(BaseModel):
name: str
price: str # 应为 float
quantity: str # 应为 int
```
### 2. 添加约束
```python
from pydantic import Field
# ✅ 好:带约束
class User(BaseModel):
name: str = Field(min_length=1, max_length=100)
age: int = Field(ge=0, le=120)
email: str = Field(pattern=r"^[\w\.-]+@[\w\.-]+\.\w+$")
# ❌ 差:无约束
class User(BaseModel):
name: str
age: int
email: str
```
### 3. 对分类使用 Enum
```python
# ✅ 好:固定集合使用 Enum
class Priority(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class Task(BaseModel):
title: str
priority: Priority
# ❌ 差:自由格式字符串
class Task(BaseModel):
title: str
priority: str # 可以是任意值
```
### 4. 在 Prompt 中提供上下文
```python
# ✅ 好:清晰的上下文
prompt = """
Extract product information from the following text.
Text: iPhone 15 Pro costs $999 and is currently in stock.
Product:
"""
# ❌ 差:上下文不足
prompt = "iPhone 15 Pro costs $999 and is currently in stock."
```
### 5. 处理可选字段
```python
from typing import Optional
# ✅ 好:对不完整数据使用可选字段
class Article(BaseModel):
title: str # 必填
author: Optional[str] = None # 可选
date: Optional[str] = None # 可选
tags: list[str] = [] # 默认空列表
# 即使 author/date 缺失也能成功
```
## 与替代方案的对比
| 特性 | Outlines | Instructor | Guidance | LMQL |
|---------|----------|------------|----------|------|
| Pydantic 支持 | ✅ 原生 | ✅ 原生 | ❌ 无 | ❌ 无 |
| JSON Schema | ✅ 支持 | ✅ 支持 | ⚠️ 有限 | ✅ 支持 |
| Regex 约束 | ✅ 支持 | ❌ 无 | ✅ 支持 | ✅ 支持 |
| 本地模型 | ✅ 完整 | ⚠️ 有限 | ✅ 完整 | ✅ 完整 |
| API 模型 | ⚠️ 有限 | ✅ 完整 | ✅ 完整 | ✅ 完整 |
| 零开销 | ✅ 支持 | ❌ 无 | ⚠️ 部分 | ✅ 支持 |
| 自动重试 | ❌ 无 | ✅ 支持 | ❌ 无 | ❌ 无 |
| 学习曲线 | 低 | 低 | 低 | 高 |
**何时选择 Outlines**
- 使用本地模型(Transformers、llama.cpp、vLLM
- 需要最大推理速度
- 需要 Pydantic 模型支持
- 需要零开销结构化生成
- 需要控制 token 采样过程
**何时选择替代方案:**
- Instructor:需要 API 模型并支持自动重试
- Guidance:需要 token healing 和复杂工作流
- LMQL:偏好声明式查询语法
## 性能特性
**速度:**
- **零开销**:结构化生成与无约束生成同样快速
- **快速前进优化**:跳过确定性 token
- **比生成后验证方案快 1.2–2 倍**
**内存:**
- FSM 每个 schema 编译一次(已缓存)
- 极低的运行时开销
- 配合 vLLM 可实现高吞吐量
**准确性:**
- **100% 有效输出**(由 FSM 保证)
- 无需重试循环
- 确定性 token 过滤
## 资源
- **文档**https://outlines-dev.github.io/outlines
- **GitHub**https://github.com/outlines-dev/outlines8k+ stars
- **Discord**https://discord.gg/R9DSu34mGd
- **博客**https://blog.dottxt.co
## 另请参阅
- `references/json_generation.md` — 全面的 JSON 与 Pydantic 模式
- `references/backends.md` — 后端专项配置
- `references/examples.md` — 生产就绪示例
@@ -0,0 +1,759 @@
---
title: "Instructor"
sidebar_label: "Instructor"
description: "使用 Pydantic 验证从 LLM 响应中提取结构化数据,自动重试失败的提取,以类型安全方式解析复杂 JSON,并使用 Instructor 流式传输部分结果——经过实战检验的结构化输出库"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Instructor
使用 Pydantic 验证从 LLM 响应中提取结构化数据,自动重试失败的提取,以类型安全方式解析复杂 JSON,并使用 Instructor 流式传输部分结果——经过实战检验的结构化输出库
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/instructor` 安装 |
| 路径 | `optional-skills/mlops/instructor` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `instructor`, `pydantic`, `openai`, `anthropic` |
| 平台 | linux, macos, windows |
| 标签 | `Prompt Engineering`, `Instructor`, `Structured Output`, `Pydantic`, `Data Extraction`, `JSON Parsing`, `Type Safety`, `Validation`, `Streaming`, `OpenAI`, `Anthropic` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# Instructor:结构化 LLM 输出
## 何时使用此 Skill
在以下情况下使用 Instructor
- **从 LLM 响应中可靠地提取结构化数据**
- **根据 Pydantic schema 自动验证输出**
- **通过自动错误处理重试失败的提取**
- **以类型安全和验证方式解析复杂 JSON**
- **流式传输部分结果**以进行实时处理
- **以一致的 API 支持多个 LLM 提供商**
**GitHub Stars**15,000+**实战检验**100,000+ 开发者
## 安装
```bash
# 基础安装
pip install instructor
# 指定提供商
pip install "instructor[anthropic]" # Anthropic Claude
pip install "instructor[openai]" # OpenAI
pip install "instructor[all]" # 所有提供商
```
## 快速开始
### 基础示例:提取用户数据
```python
import instructor
from pydantic import BaseModel
from anthropic import Anthropic
# Define output structure
class User(BaseModel):
name: str
age: int
email: str
# Create instructor client
client = instructor.from_anthropic(Anthropic())
# Extract structured data
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "John Doe is 30 years old. His email is john@example.com"
}],
response_model=User
)
print(user.name) # "John Doe"
print(user.age) # 30
print(user.email) # "john@example.com"
```
### 使用 OpenAI
```python
from openai import OpenAI
client = instructor.from_openai(OpenAI())
user = client.chat.completions.create(
model="gpt-4o-mini",
response_model=User,
messages=[{"role": "user", "content": "Extract: Alice, 25, alice@email.com"}]
)
```
## 核心概念
### 1. 响应模型(Pydantic
响应模型定义 LLM 输出的结构和验证规则。
#### 基础模型
```python
from pydantic import BaseModel, Field
class Article(BaseModel):
title: str = Field(description="Article title")
author: str = Field(description="Author name")
word_count: int = Field(description="Number of words", gt=0)
tags: list[str] = Field(description="List of relevant tags")
article = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Analyze this article: [article text]"
}],
response_model=Article
)
```
**优势:**
- 使用 Python 类型提示保证类型安全
- 自动验证(word_count > 0
- 通过 Field 描述实现自文档化
- IDE 自动补全支持
#### 嵌套模型
```python
class Address(BaseModel):
street: str
city: str
country: str
class Person(BaseModel):
name: str
age: int
address: Address # Nested model
person = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "John lives at 123 Main St, Boston, USA"
}],
response_model=Person
)
print(person.address.city) # "Boston"
```
#### 可选字段
```python
from typing import Optional
class Product(BaseModel):
name: str
price: float
discount: Optional[float] = None # Optional
description: str = Field(default="No description") # Default value
# LLM doesn't need to provide discount or description
```
#### 使用枚举约束值
```python
from enum import Enum
class Sentiment(str, Enum):
POSITIVE = "positive"
NEGATIVE = "negative"
NEUTRAL = "neutral"
class Review(BaseModel):
text: str
sentiment: Sentiment # Only these 3 values allowed
review = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "This product is amazing!"
}],
response_model=Review
)
print(review.sentiment) # Sentiment.POSITIVE
```
### 2. 验证
Pydantic 自动验证 LLM 输出。若验证失败,Instructor 会自动重试。
#### 内置验证器
```python
from pydantic import Field, EmailStr, HttpUrl
class Contact(BaseModel):
name: str = Field(min_length=2, max_length=100)
age: int = Field(ge=0, le=120) # 0 <= age <= 120
email: EmailStr # Validates email format
website: HttpUrl # Validates URL format
# If LLM provides invalid data, Instructor retries automatically
```
#### 自定义验证器
```python
from pydantic import field_validator
class Event(BaseModel):
name: str
date: str
attendees: int
@field_validator('date')
def validate_date(cls, v):
"""Ensure date is in YYYY-MM-DD format."""
import re
if not re.match(r'\d{4}-\d{2}-\d{2}', v):
raise ValueError('Date must be YYYY-MM-DD format')
return v
@field_validator('attendees')
def validate_attendees(cls, v):
"""Ensure positive attendees."""
if v < 1:
raise ValueError('Must have at least 1 attendee')
return v
```
#### 模型级验证
```python
from pydantic import model_validator
class DateRange(BaseModel):
start_date: str
end_date: str
@model_validator(mode='after')
def check_dates(self):
"""Ensure end_date is after start_date."""
from datetime import datetime
start = datetime.strptime(self.start_date, '%Y-%m-%d')
end = datetime.strptime(self.end_date, '%Y-%m-%d')
if end < start:
raise ValueError('end_date must be after start_date')
return self
```
### 3. 自动重试
当验证失败时,Instructor 会自动重试,并将错误反馈提供给 LLM。
```python
# Retries up to 3 times if validation fails
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Extract user from: John, age unknown"
}],
response_model=User,
max_retries=3 # Default is 3
)
# If age can't be extracted, Instructor tells the LLM:
# "Validation error: age - field required"
# LLM tries again with better extraction
```
**工作原理:**
1. LLM 生成输出
2. Pydantic 进行验证
3. 若无效:将错误信息发回给 LLM
4. LLM 根据错误反馈重新尝试
5. 重复直至达到 max_retries 次数
### 4. 流式传输
流式传输部分结果以进行实时处理。
#### 流式传输部分对象
```python
from instructor import Partial
class Story(BaseModel):
title: str
content: str
tags: list[str]
# Stream partial updates as LLM generates
for partial_story in client.messages.create_partial(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Write a short sci-fi story"
}],
response_model=Story
):
print(f"Title: {partial_story.title}")
print(f"Content so far: {partial_story.content[:100]}...")
# Update UI in real-time
```
#### 流式传输可迭代对象
```python
class Task(BaseModel):
title: str
priority: str
# Stream list items as they're generated
tasks = client.messages.create_iterable(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Generate 10 project tasks"
}],
response_model=Task
)
for task in tasks:
print(f"- {task.title} ({task.priority})")
# Process each task as it arrives
```
## 提供商配置
### Anthropic Claude
```python
import instructor
from anthropic import Anthropic
client = instructor.from_anthropic(
Anthropic(api_key="your-api-key")
)
# Use with Claude models
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[...],
response_model=YourModel
)
```
### OpenAI
```python
from openai import OpenAI
client = instructor.from_openai(
OpenAI(api_key="your-api-key")
)
response = client.chat.completions.create(
model="gpt-4o-mini",
response_model=YourModel,
messages=[...]
)
```
### 本地模型(Ollama
```python
from openai import OpenAI
# Point to local Ollama server
client = instructor.from_openai(
OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama" # Required but ignored
),
mode=instructor.Mode.JSON
)
response = client.chat.completions.create(
model="llama3.1",
response_model=YourModel,
messages=[...]
)
```
## 常用模式
### 模式 1:从文本中提取数据
```python
class CompanyInfo(BaseModel):
name: str
founded_year: int
industry: str
employees: int
headquarters: str
text = """
Tesla, Inc. was founded in 2003. It operates in the automotive and energy
industry with approximately 140,000 employees. The company is headquartered
in Austin, Texas.
"""
company = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"Extract company information from: {text}"
}],
response_model=CompanyInfo
)
```
### 模式 2:分类
```python
class Category(str, Enum):
TECHNOLOGY = "technology"
FINANCE = "finance"
HEALTHCARE = "healthcare"
EDUCATION = "education"
OTHER = "other"
class ArticleClassification(BaseModel):
category: Category
confidence: float = Field(ge=0.0, le=1.0)
keywords: list[str]
classification = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Classify this article: [article text]"
}],
response_model=ArticleClassification
)
```
### 模式 3:多实体提取
```python
class Person(BaseModel):
name: str
role: str
class Organization(BaseModel):
name: str
industry: str
class Entities(BaseModel):
people: list[Person]
organizations: list[Organization]
locations: list[str]
text = "Tim Cook, CEO of Apple, announced at the event in Cupertino..."
entities = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"Extract all entities from: {text}"
}],
response_model=Entities
)
for person in entities.people:
print(f"{person.name} - {person.role}")
```
### 模式 4:结构化分析
```python
class SentimentAnalysis(BaseModel):
overall_sentiment: Sentiment
positive_aspects: list[str]
negative_aspects: list[str]
suggestions: list[str]
score: float = Field(ge=-1.0, le=1.0)
review = "The product works well but setup was confusing..."
analysis = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"Analyze this review: {review}"
}],
response_model=SentimentAnalysis
)
```
### 模式 5:批量处理
```python
def extract_person(text: str) -> Person:
return client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"Extract person from: {text}"
}],
response_model=Person
)
texts = [
"John Doe is a 30-year-old engineer",
"Jane Smith, 25, works in marketing",
"Bob Johnson, age 40, software developer"
]
people = [extract_person(text) for text in texts]
```
## 高级特性
### 联合类型
```python
from typing import Union
class TextContent(BaseModel):
type: str = "text"
content: str
class ImageContent(BaseModel):
type: str = "image"
url: HttpUrl
caption: str
class Post(BaseModel):
title: str
content: Union[TextContent, ImageContent] # Either type
# LLM chooses appropriate type based on content
```
### 动态模型
```python
from pydantic import create_model
# Create model at runtime
DynamicUser = create_model(
'User',
name=(str, ...),
age=(int, Field(ge=0)),
email=(EmailStr, ...)
)
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[...],
response_model=DynamicUser
)
```
### 自定义模式
```python
# For providers without native structured outputs
client = instructor.from_anthropic(
Anthropic(),
mode=instructor.Mode.JSON # JSON mode
)
# Available modes:
# - Mode.ANTHROPIC_TOOLS (recommended for Claude)
# - Mode.JSON (fallback)
# - Mode.TOOLS (OpenAI tools)
```
### 上下文管理
```python
# Single-use client
with instructor.from_anthropic(Anthropic()) as client:
result = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[...],
response_model=YourModel
)
# Client closed automatically
```
## 错误处理
### 处理验证错误
```python
from pydantic import ValidationError
try:
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[...],
response_model=User,
max_retries=3
)
except ValidationError as e:
print(f"Failed after retries: {e}")
# Handle gracefully
except Exception as e:
print(f"API error: {e}")
```
### 自定义错误信息
```python
class ValidatedUser(BaseModel):
name: str = Field(description="Full name, 2-100 characters")
age: int = Field(description="Age between 0 and 120", ge=0, le=120)
email: EmailStr = Field(description="Valid email address")
class Config:
# Custom error messages
json_schema_extra = {
"examples": [
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
]
}
```
## 最佳实践
### 1. 清晰的字段描述
```python
# ❌ Bad: Vague
class Product(BaseModel):
name: str
price: float
# ✅ Good: Descriptive
class Product(BaseModel):
name: str = Field(description="Product name from the text")
price: float = Field(description="Price in USD, without currency symbol")
```
### 2. 使用适当的验证
```python
# ✅ Good: Constrain values
class Rating(BaseModel):
score: int = Field(ge=1, le=5, description="Rating from 1 to 5 stars")
review: str = Field(min_length=10, description="Review text, at least 10 chars")
```
### 3. 在 prompt(提示词)中提供示例
```python
messages = [{
"role": "user",
"content": """Extract person info from: "John, 30, engineer"
Example format:
{
"name": "John Doe",
"age": 30,
"occupation": "engineer"
}"""
}]
```
### 4. 对固定类别使用枚举
```python
# ✅ Good: Enum ensures valid values
class Status(str, Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
class Application(BaseModel):
status: Status # LLM must choose from enum
```
### 5. 优雅处理缺失数据
```python
class PartialData(BaseModel):
required_field: str
optional_field: Optional[str] = None
default_field: str = "default_value"
# LLM only needs to provide required_field
```
## 与其他方案的对比
| 特性 | Instructor | 手动 JSON | LangChain | DSPy |
|---------|------------|-------------|-----------|------|
| 类型安全 | ✅ 是 | ❌ 否 | ⚠️ 部分 | ✅ 是 |
| 自动验证 | ✅ 是 | ❌ 否 | ❌ 否 | ⚠️ 有限 |
| 自动重试 | ✅ 是 | ❌ 否 | ❌ 否 | ✅ 是 |
| 流式传输 | ✅ 是 | ❌ 否 | ✅ 是 | ❌ 否 |
| 多提供商 | ✅ 是 | ⚠️ 手动 | ✅ 是 | ✅ 是 |
| 学习曲线 | 低 | 低 | 中 | 高 |
**何时选择 Instructor**
- 需要结构化、经过验证的输出
- 需要类型安全和 IDE 支持
- 需要自动重试
- 构建数据提取系统
**何时选择其他方案:**
- DSPy:需要 prompt 优化
- LangChain:构建复杂链路
- 手动:简单的一次性提取
## 资源
- **文档**https://python.useinstructor.com
- **GitHub**https://github.com/jxnl/instructor15k+ stars
- **Cookbook**https://python.useinstructor.com/examples
- **Discord**:提供社区支持
## 另请参阅
- `references/validation.md` — 高级验证模式
- `references/providers.md` — 提供商专项配置
- `references/examples.md` — 真实使用案例
@@ -0,0 +1,568 @@
---
title: "Lambda Labs Gpu Cloud — 用于 ML 训练和推理的预留及按需 GPU 云实例"
sidebar_label: "Lambda Labs Gpu Cloud"
description: "用于 ML 训练和推理的预留及按需 GPU 云实例"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Lambda Labs Gpu Cloud
用于 ML 训练和推理的预留及按需 GPU 云实例。当你需要具备简单 SSH 访问的专用 GPU 实例、持久化文件系统,或用于大规模训练的高性能多节点集群时,请使用此 skill。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/lambda-labs` 安装 |
| 路径 | `optional-skills/mlops/lambda-labs` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `lambda-cloud-client>=1.0.0` |
| 平台 | linux, macos, windows |
| 标签 | `Infrastructure`, `GPU Cloud`, `Training`, `Inference`, `Lambda Labs` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Lambda Labs GPU Cloud
在 Lambda Labs GPU 云上运行 ML 工作负载的综合指南,涵盖按需实例和 1-Click Clusters。
## 何时使用 Lambda Labs
**在以下情况下使用 Lambda Labs**
- 需要具备完整 SSH 访问权限的专用 GPU 实例
- 运行长时间训练任务(数小时至数天)
- 希望简单定价且无出口费用
- 需要跨会话的持久化存储
- 需要高性能多节点集群(16-512 个 GPU)
- 希望使用预装 ML 栈(Lambda Stack,含 PyTorch、CUDA、NCCL
**主要特性:**
- **GPU 种类**B200、H100、GH200、A100、A10、A6000、V100
- **Lambda Stack**:预装 PyTorch、TensorFlow、CUDA、cuDNN、NCCL
- **持久化文件系统**:实例重启后数据保留
- **1-Click Clusters**16-512 个 GPU 的 Slurm 集群,配备 InfiniBand
- **简单定价**:按分钟计费,无出口费用
- **全球区域**:全球 12+ 个区域
**以下情况请使用替代方案:**
- **Modal**:用于无服务器、自动扩缩容工作负载
- **SkyPilot**:用于多云编排和成本优化
- **RunPod**:用于更便宜的竞价实例和无服务器端点
- **Vast.ai**:用于价格最低的 GPU 市场
## 快速开始
### 账户设置
1. 在 https://lambda.ai 创建账户
2. 添加付款方式
3. 从控制台生成 API 密钥
4. 添加 SSH 密钥(启动实例前必须完成)
### 通过控制台启动
1. 前往 https://cloud.lambda.ai/instances
2. 点击"Launch instance"
3. 选择 GPU 类型和区域
4. 选择 SSH 密钥
5. 可选择挂载文件系统
6. 启动并等待 3-15 分钟
### 通过 SSH 连接
```bash
# 从控制台获取实例 IP
ssh ubuntu@<INSTANCE-IP>
# 或使用指定密钥
ssh -i ~/.ssh/lambda_key ubuntu@<INSTANCE-IP>
```
## GPU 实例
### 可用 GPU
| GPU | 显存 | 价格/GPU/小时 | 最适用场景 |
|-----|------|--------------|----------|
| B200 SXM6 | 180 GB | $4.99 | 最大模型,最快训练 |
| H100 SXM | 80 GB | $2.99-3.29 | 大模型训练 |
| H100 PCIe | 80 GB | $2.49 | 性价比 H100 |
| GH200 | 96 GB | $1.49 | 单 GPU 大模型 |
| A100 80GB | 80 GB | $1.79 | 生产训练 |
| A100 40GB | 40 GB | $1.29 | 标准训练 |
| A10 | 24 GB | $0.75 | 推理、微调 |
| A6000 | 48 GB | $0.80 | 显存/价格比优 |
| V100 | 16 GB | $0.55 | 低成本训练 |
### 实例配置
```
8x GPU: 最适合分布式训练(DDP、FSDP)
4x GPU: 大模型、多 GPU 训练
2x GPU: 中等工作负载
1x GPU: 微调、推理、开发
```
### 启动时间
- 单 GPU3-5 分钟
- 多 GPU10-15 分钟
## Lambda Stack
所有实例均预装 Lambda Stack
```bash
# 包含软件
- Ubuntu 22.04 LTS
- NVIDIA drivers (latest)
- CUDA 12.x
- cuDNN 8.x
- NCCL (for multi-GPU)
- PyTorch (latest)
- TensorFlow (latest)
- JAX
- JupyterLab
```
### 验证安装
```bash
# 检查 GPU
nvidia-smi
# 检查 PyTorch
python -c "import torch; print(torch.cuda.is_available())"
# 检查 CUDA 版本
nvcc --version
```
## Python API
### 安装
```bash
pip install lambda-cloud-client
```
### 认证
```python
import os
import lambda_cloud_client
# 使用 API 密钥配置
configuration = lambda_cloud_client.Configuration(
host="https://cloud.lambdalabs.com/api/v1",
access_token=os.environ["LAMBDA_API_KEY"]
)
```
### 列出可用实例
```python
with lambda_cloud_client.ApiClient(configuration) as api_client:
api = lambda_cloud_client.DefaultApi(api_client)
# 获取可用实例类型
types = api.instance_types()
for name, info in types.data.items():
print(f"{name}: {info.instance_type.description}")
```
### 启动实例
```python
from lambda_cloud_client.models import LaunchInstanceRequest
request = LaunchInstanceRequest(
region_name="us-west-1",
instance_type_name="gpu_1x_h100_sxm5",
ssh_key_names=["my-ssh-key"],
file_system_names=["my-filesystem"], # 可选
name="training-job"
)
response = api.launch_instance(request)
instance_id = response.data.instance_ids[0]
print(f"Launched: {instance_id}")
```
### 列出运行中的实例
```python
instances = api.list_instances()
for instance in instances.data:
print(f"{instance.name}: {instance.ip} ({instance.status})")
```
### 终止实例
```python
from lambda_cloud_client.models import TerminateInstanceRequest
request = TerminateInstanceRequest(
instance_ids=[instance_id]
)
api.terminate_instance(request)
```
### SSH 密钥管理
```python
from lambda_cloud_client.models import AddSshKeyRequest
# 添加 SSH 密钥
request = AddSshKeyRequest(
name="my-key",
public_key="ssh-rsa AAAA..."
)
api.add_ssh_key(request)
# 列出密钥
keys = api.list_ssh_keys()
# 删除密钥
api.delete_ssh_key(key_id)
```
## 使用 curl 的 CLI
### 列出实例类型
```bash
curl -u $LAMBDA_API_KEY: \
https://cloud.lambdalabs.com/api/v1/instance-types | jq
```
### 启动实例
```bash
curl -u $LAMBDA_API_KEY: \
-X POST https://cloud.lambdalabs.com/api/v1/instance-operations/launch \
-H "Content-Type: application/json" \
-d '{
"region_name": "us-west-1",
"instance_type_name": "gpu_1x_h100_sxm5",
"ssh_key_names": ["my-key"]
}' | jq
```
### 终止实例
```bash
curl -u $LAMBDA_API_KEY: \
-X POST https://cloud.lambdalabs.com/api/v1/instance-operations/terminate \
-H "Content-Type: application/json" \
-d '{"instance_ids": ["<INSTANCE-ID>"]}' | jq
```
## 持久化存储
### 文件系统
文件系统在实例重启后保留数据:
```bash
# 挂载位置
/lambda/nfs/<FILESYSTEM_NAME>
# 示例:保存检查点
python train.py --checkpoint-dir /lambda/nfs/my-storage/checkpoints
```
### 创建文件系统
1. 前往 Lambda 控制台中的 Storage
2. 点击"Create filesystem"
3. 选择区域(必须与实例区域一致)
4. 命名并创建
### 挂载到实例
文件系统必须在实例启动时挂载:
- 通过控制台:启动时选择文件系统
- 通过 API:在启动请求中包含 `file_system_names`
### 最佳实践
<!-- ascii-guard-ignore -->
```bash
# 存储在文件系统上(持久化)
/lambda/nfs/storage/
├── datasets/
├── checkpoints/
├── models/
└── outputs/
# 本地 SSD(更快,临时)
/home/ubuntu/
└── working/ # 临时文件
```
<!-- ascii-guard-ignore-end -->
## SSH 配置
### 添加 SSH 密钥
```bash
# 在本地生成密钥
ssh-keygen -t ed25519 -f ~/.ssh/lambda_key
# 将公钥添加到 Lambda 控制台
# 或通过 API 添加
```
### 多个密钥
```bash
# 在实例上添加更多密钥
echo 'ssh-rsa AAAA...' >> ~/.ssh/authorized_keys
```
### 从 GitHub 导入
```bash
# 在实例上执行
ssh-import-id gh:username
```
### SSH 隧道
```bash
# 转发 Jupyter
ssh -L 8888:localhost:8888 ubuntu@<IP>
# 转发 TensorBoard
ssh -L 6006:localhost:6006 ubuntu@<IP>
# 多端口
ssh -L 8888:localhost:8888 -L 6006:localhost:6006 ubuntu@<IP>
```
## JupyterLab
### 从控制台启动
1. 前往 Instances 页面
2. 点击 Cloud IDE 列中的"Launch"
3. JupyterLab 在浏览器中打开
### 手动访问
```bash
# 在实例上
jupyter lab --ip=0.0.0.0 --port=8888
# 在本地机器上建立隧道
ssh -L 8888:localhost:8888 ubuntu@<IP>
# 打开 http://localhost:8888
```
## 训练工作流
### 单 GPU 训练
```bash
# SSH 到实例
ssh ubuntu@<IP>
# 克隆仓库
git clone https://github.com/user/project
cd project
# 安装依赖
pip install -r requirements.txt
# 训练
python train.py --epochs 100 --checkpoint-dir /lambda/nfs/storage/checkpoints
```
### 多 GPU 训练(单节点)
```python
# train_ddp.py
import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
def main():
dist.init_process_group("nccl")
rank = dist.get_rank()
device = rank % torch.cuda.device_count()
model = MyModel().to(device)
model = DDP(model, device_ids=[device])
# 训练循环...
if __name__ == "__main__":
main()
```
```bash
# 使用 torchrun 启动(8 个 GPU
torchrun --nproc_per_node=8 train_ddp.py
```
### 检查点保存到文件系统
```python
import os
checkpoint_dir = "/lambda/nfs/my-storage/checkpoints"
os.makedirs(checkpoint_dir, exist_ok=True)
# 保存检查点
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
}, f"{checkpoint_dir}/checkpoint_{epoch}.pt")
```
## 1-Click Clusters
### 概述
高性能 Slurm 集群,具备:
- 16-512 个 NVIDIA H100 或 B200 GPU
- NVIDIA Quantum-2 400 Gb/s InfiniBand
- GPUDirect RDMA,速率 3200 Gb/s
- 预装分布式 ML 栈
### 包含软件
- Ubuntu 22.04 LTS + Lambda Stack
- NCCL、Open MPI
- PyTorch(含 DDP 和 FSDP
- TensorFlow
- OFED 驱动
### 存储
- 每个计算节点 24 TB NVMe(临时)
- Lambda 文件系统用于持久化数据
### 多节点训练
```bash
# 在 Slurm 集群上
srun --nodes=4 --ntasks-per-node=8 --gpus-per-node=8 \
torchrun --nnodes=4 --nproc_per_node=8 \
--rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR:29500 \
train.py
```
## 网络
### 带宽
- 实例间(同一区域):最高 200 Gbps
- 互联网出站:最高 20 Gbps
### 防火墙
- 默认:仅开放 22 端口(SSH
- 在 Lambda 控制台中配置其他端口
- 默认允许 ICMP 流量
### 私有 IP
```bash
# 查找私有 IP
ip addr show | grep 'inet '
```
## 常见工作流
### 工作流 1:微调 LLM
```bash
# 1. 启动带文件系统的 8x H100 实例
# 2. SSH 并设置环境
ssh ubuntu@<IP>
pip install transformers accelerate peft
# 3. 将模型下载到文件系统
python -c "
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained('meta-llama/Llama-2-7b-hf')
model.save_pretrained('/lambda/nfs/storage/models/llama-2-7b')
"
# 4. 使用文件系统上的检查点进行微调
accelerate launch --num_processes 8 train.py \
--model_path /lambda/nfs/storage/models/llama-2-7b \
--output_dir /lambda/nfs/storage/outputs \
--checkpoint_dir /lambda/nfs/storage/checkpoints
```
### 工作流 2:批量推理
```bash
# 1. 启动 A10 实例(推理性价比高)
# 2. 运行推理
python inference.py \
--model /lambda/nfs/storage/models/fine-tuned \
--input /lambda/nfs/storage/data/inputs.jsonl \
--output /lambda/nfs/storage/data/outputs.jsonl
```
## 成本优化
### 选择合适的 GPU
| 任务 | 推荐 GPU |
|------|-----------------|
| LLM 微调(7B | A100 40GB |
| LLM 微调(70B | 8x H100 |
| 推理 | A10、A6000 |
| 开发 | V100、A10 |
| 最高性能 | B200 |
### 降低成本
1. **使用文件系统**:避免重复下载数据
2. **频繁保存检查点**:恢复中断的训练
3. **合理配置**:不要过度分配 GPU
4. **终止空闲实例**:无自动停止,需手动终止
### 监控使用情况
- 控制台显示实时 GPU 利用率
- 通过 API 进行程序化监控
## 常见问题
| 问题 | 解决方案 |
|-------|----------|
| 实例无法启动 | 检查区域可用性,尝试不同 GPU |
| SSH 连接被拒绝 | 等待实例初始化(3-15 分钟) |
| 终止后数据丢失 | 使用持久化文件系统 |
| 数据传输缓慢 | 使用同一区域的文件系统 |
| GPU 未被检测到 | 重启实例,检查驱动 |
## 参考资料
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/lambda-labs/references/advanced-usage.md)** — 多节点训练、API 自动化
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/lambda-labs/references/troubleshooting.md)** — 常见问题及解决方案
## 资源
- **文档**https://docs.lambda.ai
- **控制台**https://cloud.lambda.ai
- **定价**https://lambda.ai/instances
- **支持**https://support.lambdalabs.com
- **博客**https://lambda.ai/blog
@@ -0,0 +1,323 @@
---
title: "Llava — 大型语言与视觉助手"
sidebar_label: "Llava"
description: "大型语言与视觉助手"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Llava
大型语言与视觉助手。支持视觉指令微调(instruction tuning)和基于图像的对话。将 CLIP 视觉编码器与 Vicuna/LLaMA 语言模型相结合。支持多轮图像对话、视觉问答(VQA)和指令跟随。适用于视觉语言聊天机器人或图像理解任务。最适合对话式图像分析。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/llava` 安装 |
| 路径 | `optional-skills/mlops/llava` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `transformers`, `torch`, `pillow` |
| 平台 | linux, macos, windows |
| 标签 | `LLaVA`, `Vision-Language`, `Multimodal`, `Visual Question Answering`, `Image Chat`, `CLIP`, `Vicuna`, `Conversational AI`, `Instruction Tuning`, `VQA` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# LLaVA - 大型语言与视觉助手
用于对话式图像理解的开源视觉语言模型。
## 何时使用 LLaVA
**适用场景:**
- 构建视觉语言聊天机器人
- 视觉问答(VQA
- 图像描述与字幕生成
- 多轮图像对话
- 视觉指令跟随
- 含图像的文档理解
**指标**
- **GitHub 23,000+ 星标**
- GPT-4V 级别能力(目标)
- Apache 2.0 许可证
- 多种模型规格(7B34B 参数)
**改用其他方案的情况**
- **GPT-4V**:质量最高,基于 API
- **CLIP**:简单零样本分类
- **BLIP-2**:更适合纯字幕生成
- **Flamingo**:研究用途,非开源
## 快速开始
### 安装
```bash
# Clone repository
git clone https://github.com/haotian-liu/LLaVA
cd LLaVA
# Install
pip install -e .
```
### 基本用法
```python
from llava.model.builder import load_pretrained_model
from llava.mm_utils import get_model_name_from_path, process_images, tokenizer_image_token
from llava.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN
from llava.conversation import conv_templates
from PIL import Image
import torch
# Load model
model_path = "liuhaotian/llava-v1.5-7b"
tokenizer, model, image_processor, context_len = load_pretrained_model(
model_path=model_path,
model_base=None,
model_name=get_model_name_from_path(model_path)
)
# Load image
image = Image.open("image.jpg")
image_tensor = process_images([image], image_processor, model.config)
image_tensor = image_tensor.to(model.device, dtype=torch.float16)
# Create conversation
conv = conv_templates["llava_v1"].copy()
conv.append_message(conv.roles[0], DEFAULT_IMAGE_TOKEN + "\nWhat is in this image?")
conv.append_message(conv.roles[1], None)
prompt = conv.get_prompt()
# Generate response
input_ids = tokenizer_image_token(prompt, tokenizer, IMAGE_TOKEN_INDEX, return_tensors='pt').unsqueeze(0).to(model.device)
with torch.inference_mode():
output_ids = model.generate(
input_ids,
images=image_tensor,
do_sample=True,
temperature=0.2,
max_new_tokens=512
)
response = tokenizer.decode(output_ids[0], skip_special_tokens=True).strip()
print(response)
```
## 可用模型
| 模型 | 参数量 | 显存 | 质量 |
|-------|------------|------|---------|
| LLaVA-v1.5-7B | 7B | ~14 GB | 良好 |
| LLaVA-v1.5-13B | 13B | ~28 GB | 较好 |
| LLaVA-v1.6-34B | 34B | ~70 GB | 最佳 |
```python
# Load different models
model_7b = "liuhaotian/llava-v1.5-7b"
model_13b = "liuhaotian/llava-v1.5-13b"
model_34b = "liuhaotian/llava-v1.6-34b"
# 4-bit quantization for lower VRAM
load_4bit = True # Reduces VRAM by ~4×
```
## CLI 用法
```bash
# Single image query
python -m llava.serve.cli \
--model-path liuhaotian/llava-v1.5-7b \
--image-file image.jpg \
--query "What is in this image?"
# Multi-turn conversation
python -m llava.serve.cli \
--model-path liuhaotian/llava-v1.5-7b \
--image-file image.jpg
# Then type questions interactively
```
## Web UIGradio
```bash
# Launch Gradio interface
python -m llava.serve.gradio_web_server \
--model-path liuhaotian/llava-v1.5-7b \
--load-4bit # Optional: reduce VRAM
# Access at http://localhost:7860
```
## 多轮对话
```python
# Initialize conversation
conv = conv_templates["llava_v1"].copy()
# Turn 1
conv.append_message(conv.roles[0], DEFAULT_IMAGE_TOKEN + "\nWhat is in this image?")
conv.append_message(conv.roles[1], None)
response1 = generate(conv, model, image) # "A dog playing in a park"
# Turn 2
conv.messages[-1][1] = response1 # Add previous response
conv.append_message(conv.roles[0], "What breed is the dog?")
conv.append_message(conv.roles[1], None)
response2 = generate(conv, model, image) # "Golden Retriever"
# Turn 3
conv.messages[-1][1] = response2
conv.append_message(conv.roles[0], "What time of day is it?")
conv.append_message(conv.roles[1], None)
response3 = generate(conv, model, image)
```
## 常见任务
### 图像字幕生成
```python
question = "Describe this image in detail."
response = ask(model, image, question)
```
### 视觉问答
```python
question = "How many people are in the image?"
response = ask(model, image, question)
```
### 目标检测(文本形式)
```python
question = "List all the objects you can see in this image."
response = ask(model, image, question)
```
### 场景理解
```python
question = "What is happening in this scene?"
response = ask(model, image, question)
```
### 文档理解
```python
question = "What is the main topic of this document?"
response = ask(model, document_image, question)
```
## 训练自定义模型
```bash
# Stage 1: Feature alignment (558K image-caption pairs)
bash scripts/v1_5/pretrain.sh
# Stage 2: Visual instruction tuning (150K instruction data)
bash scripts/v1_5/finetune.sh
```
## 量化(降低显存占用)
```python
# 4-bit quantization
tokenizer, model, image_processor, context_len = load_pretrained_model(
model_path="liuhaotian/llava-v1.5-13b",
model_base=None,
model_name=get_model_name_from_path("liuhaotian/llava-v1.5-13b"),
load_4bit=True # Reduces VRAM ~4×
)
# 8-bit quantization
load_8bit=True # Reduces VRAM ~2×
```
## 最佳实践
1. **从 7B 模型开始** — 质量良好,显存需求可控
2. **使用 4-bit 量化** — 显著降低显存占用
3. **需要 GPU** — CPU 推理极慢
4. **清晰的 prompt** — 具体问题能获得更好的答案
5. **多轮对话** — 保持对话上下文
6. **温度 0.20.7** — 平衡创造性与一致性
7. **`max_new_tokens` 5121024** — 用于详细回复
8. **批量处理** — 按顺序处理多张图像
## 性能
| 模型 | 显存(FP16 | 显存(4-bit | 速度(tokens/s |
|-------|-------------|--------------|------------------|
| 7B | ~14 GB | ~4 GB | ~20 |
| 13B | ~28 GB | ~8 GB | ~12 |
| 34B | ~70 GB | ~18 GB | ~5 |
*在 A100 GPU 上测试*
## 基准测试
LLaVA 在以下基准上取得了有竞争力的分数:
- **VQAv2**78.5%
- **GQA**62.0%
- **MM-Vet**35.4%
- **MMBench**64.3%
## 局限性
1. **幻觉** — 可能描述图像中不存在的内容
2. **空间推理** — 难以精确定位位置
3. **小字体文本** — 难以识别细小字体
4. **目标计数** — 对大量目标计数不精确
5. **显存需求** — 需要高性能 GPU
6. **推理速度** — 比 CLIP 慢
## 与框架集成
### LangChain
```python
from langchain.llms.base import LLM
class LLaVALLM(LLM):
def _call(self, prompt, stop=None):
# Custom LLaVA inference
return response
llm = LLaVALLM()
```
### Gradio 应用
```python
import gradio as gr
def chat(image, text, history):
response = ask_llava(model, image, text)
return response
demo = gr.ChatInterface(
chat,
additional_inputs=[gr.Image(type="pil")],
title="LLaVA Chat"
)
demo.launch()
```
## 资源
- **GitHub**https://github.com/haotian-liu/LLaVA ⭐ 23,000+
- **论文**https://arxiv.org/abs/2304.08485
- **演示**https://llava.hliu.cc
- **模型**https://huggingface.co/liuhaotian
- **许可证**Apache 2.0
@@ -0,0 +1,362 @@
---
title: "Modal Serverless Gpu — 用于运行 ML 工作负载的无服务器 GPU 云平台"
sidebar_label: "Modal Serverless Gpu"
description: "用于运行 ML 工作负载的无服务器 GPU 云平台"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Modal Serverless Gpu
用于运行 ML 工作负载的无服务器 GPU 云平台。适用于需要按需 GPU 访问而无需管理基础设施、将 ML 模型部署为 API,或运行具有自动扩缩容的批处理作业的场景。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/modal` 安装 |
| 路径 | `optional-skills/mlops/modal` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `modal>=0.64.0` |
| 平台 | linux, macos, windows |
| 标签 | `Infrastructure`, `Serverless`, `GPU`, `Cloud`, `Deployment`, `Modal` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Modal Serverless GPU
在 Modal 无服务器 GPU 云平台上运行 ML 工作负载的完整指南。
## 何时使用 Modal
**在以下情况下使用 Modal**
- 运行 GPU 密集型 ML 工作负载而无需管理基础设施
- 将 ML 模型部署为自动扩缩容 API
- 运行批处理作业(训练、推理、数据处理)
- 需要按秒计费的 GPU 定价,无空闲成本
- 快速原型化 ML 应用
- 运行定时作业(类 cron 工作负载)
**主要特性:**
- **无服务器 GPU**:按需提供 T4、L4、A10G、L40S、A100、H100、H200、B200
- **Python 原生**:用 Python 代码定义基础设施,无需 YAML
- **自动扩缩容**:缩容至零,或瞬间扩容至 100+ 个 GPU
- **亚秒级冷启动**:基于 Rust 的基础设施,实现快速容器启动
- **容器缓存**:镜像层缓存,支持快速迭代
- **Web 端点**:将函数部署为 REST API,支持零停机更新
**以下情况请使用替代方案:**
- **RunPod**:适用于需要持久状态的长时间运行 pod
- **Lambda Labs**:适用于预留 GPU 实例
- **SkyPilot**:适用于多云编排和成本优化
- **Kubernetes**:适用于复杂的多服务架构
## 快速开始
### 安装
```bash
pip install modal
modal setup # Opens browser for authentication
```
### GPU Hello World
```python
import modal
app = modal.App("hello-gpu")
@app.function(gpu="T4")
def gpu_info():
import subprocess
return subprocess.run(["nvidia-smi"], capture_output=True, text=True).stdout
@app.local_entrypoint()
def main():
print(gpu_info.remote())
```
运行:`modal run hello_gpu.py`
### 基础推理端点
```python
import modal
app = modal.App("text-generation")
image = modal.Image.debian_slim().pip_install("transformers", "torch", "accelerate")
@app.cls(gpu="A10G", image=image)
class TextGenerator:
@modal.enter()
def load_model(self):
from transformers import pipeline
self.pipe = pipeline("text-generation", model="gpt2", device=0)
@modal.method()
def generate(self, prompt: str) -> str:
return self.pipe(prompt, max_length=100)[0]["generated_text"]
@app.local_entrypoint()
def main():
print(TextGenerator().generate.remote("Hello, world"))
```
## 核心概念
### 关键组件
| 组件 | 用途 |
|-----------|---------|
| `App` | 函数和资源的容器 |
| `Function` | 带计算规格的无服务器函数 |
| `Cls` | 带生命周期 hook 的基于类的函数 |
| `Image` | 容器镜像定义 |
| `Volume` | 用于模型/数据的持久存储 |
| `Secret` | 安全凭证存储 |
### 执行模式
| 命令 | 描述 |
|---------|-------------|
| `modal run script.py` | 执行后退出 |
| `modal serve script.py` | 开发模式,支持热重载 |
| `modal deploy script.py` | 持久化云端部署 |
## GPU 配置
### 可用 GPU
| GPU | 显存 | 最适用于 |
|-----|------|----------|
| `T4` | 16GB | 经济型推理、小型模型 |
| `L4` | 24GB | 推理,Ada Lovelace 架构 |
| `A10G` | 24GB | 训练/推理,比 T4 快 3.3 倍 |
| `L40S` | 48GB | 推荐用于推理(最佳性价比) |
| `A100-40GB` | 40GB | 大型模型训练 |
| `A100-80GB` | 80GB | 超大型模型 |
| `H100` | 80GB | 最快,支持 FP8 + Transformer Engine |
| `H200` | 141GB | 从 H100 自动升级,4.8TB/s 带宽 |
| `B200` | 最新 | Blackwell 架构 |
### GPU 规格配置模式
```python
# Single GPU
@app.function(gpu="A100")
# Specific memory variant
@app.function(gpu="A100-80GB")
# Multiple GPUs (up to 8)
@app.function(gpu="H100:4")
# GPU with fallbacks
@app.function(gpu=["H100", "A100", "L40S"])
# Any available GPU
@app.function(gpu="any")
```
## 容器镜像
```python
# Basic image with pip
image = modal.Image.debian_slim(python_version="3.11").pip_install(
"torch==2.1.0", "transformers==4.36.0", "accelerate"
)
# From CUDA base
image = modal.Image.from_registry(
"nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04",
add_python="3.11"
).pip_install("torch", "transformers")
# With system packages
image = modal.Image.debian_slim().apt_install("git", "ffmpeg").pip_install("whisper")
```
## 持久存储
```python
volume = modal.Volume.from_name("model-cache", create_if_missing=True)
@app.function(gpu="A10G", volumes={"/models": volume})
def load_model():
import os
model_path = "/models/llama-7b"
if not os.path.exists(model_path):
model = download_model()
model.save_pretrained(model_path)
volume.commit() # Persist changes
return load_from_path(model_path)
```
## Web 端点
### FastAPI 端点装饰器
```python
@app.function()
@modal.fastapi_endpoint(method="POST")
def predict(text: str) -> dict:
return {"result": model.predict(text)}
```
### 完整 ASGI 应用
```python
from fastapi import FastAPI
web_app = FastAPI()
@web_app.post("/predict")
async def predict(text: str):
return {"result": await model.predict.remote.aio(text)}
@app.function()
@modal.asgi_app()
def fastapi_app():
return web_app
```
### Web 端点类型
| 装饰器 | 使用场景 |
|-----------|----------|
| `@modal.fastapi_endpoint()` | 简单函数 → API |
| `@modal.asgi_app()` | 完整 FastAPI/Starlette 应用 |
| `@modal.wsgi_app()` | Django/Flask 应用 |
| `@modal.web_server(port)` | 任意 HTTP 服务器 |
## 动态批处理
```python
@app.function()
@modal.batched(max_batch_size=32, wait_ms=100)
async def batch_predict(inputs: list[str]) -> list[dict]:
# Inputs automatically batched
return model.batch_predict(inputs)
```
## 密钥管理
```bash
# Create secret
modal secret create huggingface HF_TOKEN=hf_xxx
```
```python
@app.function(secrets=[modal.Secret.from_name("huggingface")])
def download_model():
import os
token = os.environ["HF_TOKEN"]
```
## 定时任务
```python
@app.function(schedule=modal.Cron("0 0 * * *")) # Daily midnight
def daily_job():
pass
@app.function(schedule=modal.Period(hours=1))
def hourly_job():
pass
```
## 性能优化
### 冷启动缓解
```python
@app.function(
container_idle_timeout=300, # Keep warm 5 min
allow_concurrent_inputs=10, # Handle concurrent requests
)
def inference():
pass
```
### 模型加载最佳实践
```python
@app.cls(gpu="A100")
class Model:
@modal.enter() # Run once at container start
def load(self):
self.model = load_model() # Load during warm-up
@modal.method()
def predict(self, x):
return self.model(x)
```
## 并行处理
```python
@app.function()
def process_item(item):
return expensive_computation(item)
@app.function()
def run_parallel():
items = list(range(1000))
# Fan out to parallel containers
results = list(process_item.map(items))
return results
```
## 常用配置
```python
@app.function(
gpu="A100",
memory=32768, # 32GB RAM
cpu=4, # 4 CPU cores
timeout=3600, # 1 hour max
container_idle_timeout=120,# Keep warm 2 min
retries=3, # Retry on failure
concurrency_limit=10, # Max concurrent containers
)
def my_function():
pass
```
## 调试
```python
# Test locally
if __name__ == "__main__":
result = my_function.local()
# View logs
# modal app logs my-app
```
## 常见问题
| 问题 | 解决方案 |
|-------|----------|
| 冷启动延迟 | 增大 `container_idle_timeout`,使用 `@modal.enter()` |
| GPU 内存溢出 | 使用更大 GPU(`A100-80GB`),启用梯度检查点 |
| 镜像构建失败 | 固定依赖版本,检查 CUDA 兼容性 |
| 超时错误 | 增大 `timeout`,添加检查点 |
## 参考资料
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/modal/references/advanced-usage.md)** - 多 GPU、分布式训练、成本优化
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/modal/references/troubleshooting.md)** - 常见问题与解决方案
## 资源
- **文档**https://modal.com/docs
- **示例**https://github.com/modal-labs/modal-examples
- **定价**https://modal.com/pricing
- **Discord**https://discord.gg/modal
@@ -0,0 +1,401 @@
---
title: "Nemo Curator — 用于 LLM 训练的 GPU 加速数据整理工具"
sidebar_label: "Nemo Curator"
description: "用于 LLM 训练的 GPU 加速数据整理工具"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Nemo Curator
用于 LLM 训练的 GPU 加速数据整理工具。支持文本/图像/视频/音频。具备模糊去重(速度提升 16×)、质量过滤(30+ 启发式规则)、语义去重、PII 脱敏、NSFW 检测等功能。通过 RAPIDS 跨 GPU 扩展。适用于准备高质量训练数据集、清洗网络数据或对大型语料库去重。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/nemo-curator` 安装 |
| 路径 | `optional-skills/mlops/nemo-curator` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `nemo-curator`, `cudf`, `dask`, `rapids` |
| 平台 | linux, macos |
| 标签 | `Data Processing`, `NeMo Curator`, `Data Curation`, `GPU Acceleration`, `Deduplication`, `Quality Filtering`, `NVIDIA`, `RAPIDS`, `PII Redaction`, `Multimodal`, `LLM Training Data` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# NeMo Curator - GPU 加速数据整理
NVIDIA 用于为 LLM 准备高质量训练数据的工具包。
## 何时使用 NeMo Curator
**在以下情况下使用 NeMo Curator**
- 从网络抓取数据(Common Crawl)准备 LLM 训练数据
- 需要快速去重(比 CPU 快 16×)
- 整理多模态数据集(文本、图像、视频、音频)
- 过滤低质量或有害内容
- 跨 GPU 集群扩展数据处理
**性能**
- **16× 更快**的模糊去重(8TB RedPajama v2
- **降低 40% TCO**(总拥有成本),优于 CPU 方案
- **近线性扩展**,跨 GPU 节点
**以下情况请使用替代方案**
- **datatrove**:基于 CPU 的开源数据处理
- **dolma**Allen AI 的数据工具包
- **Ray Data**:通用 ML 数据处理(无数据整理专项功能)
## 快速开始
### 安装
```bash
# 文本整理(CUDA 12
uv pip install "nemo-curator[text_cuda12]"
# 所有模态
uv pip install "nemo-curator[all_cuda12]"
# 仅 CPU(较慢)
uv pip install "nemo-curator[cpu]"
```
### 基础文本整理流水线
```python
from nemo_curator import ScoreFilter, Modify
from nemo_curator.datasets import DocumentDataset
import pandas as pd
# 加载数据
df = pd.DataFrame({"text": ["Good document", "Bad doc", "Excellent text"]})
dataset = DocumentDataset(df)
# 质量过滤
def quality_score(doc):
return len(doc["text"].split()) > 5 # Filter short docs
filtered = ScoreFilter(quality_score)(dataset)
# 去重
from nemo_curator.modules import ExactDuplicates
deduped = ExactDuplicates()(filtered)
# 保存
deduped.to_parquet("curated_data/")
```
## 数据整理流水线
### 阶段 1:质量过滤
```python
from nemo_curator.filters import (
WordCountFilter,
RepeatedLinesFilter,
UrlRatioFilter,
NonAlphaNumericFilter
)
# 应用 30+ 启发式过滤器
from nemo_curator import ScoreFilter
# 词数过滤
dataset = dataset.filter(WordCountFilter(min_words=50, max_words=100000))
# 去除重复内容
dataset = dataset.filter(RepeatedLinesFilter(max_repeated_line_fraction=0.3))
# URL 比例过滤
dataset = dataset.filter(UrlRatioFilter(max_url_ratio=0.2))
```
### 阶段 2:去重
**精确去重**
```python
from nemo_curator.modules import ExactDuplicates
# 删除完全重复项
deduped = ExactDuplicates(id_field="id", text_field="text")(dataset)
```
**模糊去重**(GPU 上速度提升 16×):
```python
from nemo_curator.modules import FuzzyDuplicates
# MinHash + LSH 去重
fuzzy_dedup = FuzzyDuplicates(
id_field="id",
text_field="text",
num_hashes=260, # MinHash parameters
num_buckets=20,
hash_method="md5"
)
deduped = fuzzy_dedup(dataset)
```
**语义去重**
```python
from nemo_curator.modules import SemanticDuplicates
# 基于 embedding(向量嵌入)的去重
semantic_dedup = SemanticDuplicates(
id_field="id",
text_field="text",
embedding_model="sentence-transformers/all-MiniLM-L6-v2",
threshold=0.8 # Cosine similarity threshold
)
deduped = semantic_dedup(dataset)
```
### 阶段 3PII 脱敏
```python
from nemo_curator.modules import Modify
from nemo_curator.modifiers import PIIRedactor
# 脱敏个人身份信息(PII
pii_redactor = PIIRedactor(
supported_entities=["EMAIL_ADDRESS", "PHONE_NUMBER", "PERSON", "LOCATION"],
anonymize_action="replace" # or "redact"
)
redacted = Modify(pii_redactor)(dataset)
```
### 阶段 4:分类器过滤
```python
from nemo_curator.classifiers import QualityClassifier
# 质量分类
quality_clf = QualityClassifier(
model_path="nvidia/quality-classifier-deberta",
batch_size=256,
device="cuda"
)
# 过滤低质量文档
high_quality = dataset.filter(lambda doc: quality_clf(doc["text"]) > 0.5)
```
## GPU 加速
### GPU 与 CPU 性能对比
| 操作 | CPU16 核) | GPUA100 | 加速比 |
|-----------|----------------|------------|---------|
| 模糊去重(8TB | 120 小时 | 7.5 小时 | 16× |
| 精确去重(1TB | 8 小时 | 0.5 小时 | 16× |
| 质量过滤 | 2 小时 | 0.2 小时 | 10× |
### 多 GPU 扩展
```python
from nemo_curator import get_client
import dask_cuda
# 初始化 GPU 集群
client = get_client(cluster_type="gpu", n_workers=8)
# 使用 8 块 GPU 处理
deduped = FuzzyDuplicates(...)(dataset)
```
## 多模态数据整理
### 图像整理
```python
from nemo_curator.image import (
AestheticFilter,
NSFWFilter,
CLIPEmbedder
)
# 美学评分
aesthetic_filter = AestheticFilter(threshold=5.0)
filtered_images = aesthetic_filter(image_dataset)
# NSFW 检测
nsfw_filter = NSFWFilter(threshold=0.9)
safe_images = nsfw_filter(filtered_images)
# 生成 CLIP embedding
clip_embedder = CLIPEmbedder(model="openai/clip-vit-base-patch32")
image_embeddings = clip_embedder(safe_images)
```
### 视频整理
```python
from nemo_curator.video import (
SceneDetector,
ClipExtractor,
InternVideo2Embedder
)
# 场景检测
scene_detector = SceneDetector(threshold=27.0)
scenes = scene_detector(video_dataset)
# 提取片段
clip_extractor = ClipExtractor(min_duration=2.0, max_duration=10.0)
clips = clip_extractor(scenes)
# 生成 embedding
video_embedder = InternVideo2Embedder()
video_embeddings = video_embedder(clips)
```
### 音频整理
```python
from nemo_curator.audio import (
ASRInference,
WERFilter,
DurationFilter
)
# ASR 转录
asr = ASRInference(model="nvidia/stt_en_fastconformer_hybrid_large_pc")
transcribed = asr(audio_dataset)
# 按 WER(词错误率)过滤
wer_filter = WERFilter(max_wer=0.3)
high_quality_audio = wer_filter(transcribed)
# 时长过滤
duration_filter = DurationFilter(min_duration=1.0, max_duration=30.0)
filtered_audio = duration_filter(high_quality_audio)
```
## 常见模式
### 网络抓取数据整理(Common Crawl
```python
from nemo_curator import ScoreFilter, Modify
from nemo_curator.filters import *
from nemo_curator.modules import *
from nemo_curator.datasets import DocumentDataset
# 加载 Common Crawl 数据
dataset = DocumentDataset.read_parquet("common_crawl/*.parquet")
# 流水线
pipeline = [
# 1. 质量过滤
WordCountFilter(min_words=100, max_words=50000),
RepeatedLinesFilter(max_repeated_line_fraction=0.2),
SymbolToWordRatioFilter(max_symbol_to_word_ratio=0.3),
UrlRatioFilter(max_url_ratio=0.3),
# 2. 语言过滤
LanguageIdentificationFilter(target_languages=["en"]),
# 3. 去重
ExactDuplicates(id_field="id", text_field="text"),
FuzzyDuplicates(id_field="id", text_field="text", num_hashes=260),
# 4. PII 脱敏
PIIRedactor(),
# 5. NSFW 过滤
NSFWClassifier(threshold=0.8)
]
# 执行
for stage in pipeline:
dataset = stage(dataset)
# 保存
dataset.to_parquet("curated_common_crawl/")
```
### 分布式处理
```python
from nemo_curator import get_client
from dask_cuda import LocalCUDACluster
# 多 GPU 集群
cluster = LocalCUDACluster(n_workers=8)
client = get_client(cluster=cluster)
# 处理大型数据集
dataset = DocumentDataset.read_parquet("s3://large_dataset/*.parquet")
deduped = FuzzyDuplicates(...)(dataset)
# 清理
client.close()
cluster.close()
```
## 性能基准
### 模糊去重(8TB RedPajama v2
- **CPU256 核)**120 小时
- **GPU8× A100**7.5 小时
- **加速比**16×
### 精确去重(1TB
- **CPU64 核)**8 小时
- **GPU4× A100**0.5 小时
- **加速比**16×
### 质量过滤(100GB
- **CPU32 核)**2 小时
- **GPU2× A100**0.2 小时
- **加速比**10×
## 成本对比
**基于 CPU 的数据整理**AWS c5.18xlarge × 10):
- 费用:$3.60/小时 × 10 = $36/小时
- 处理 8TB 耗时:120 小时
- **合计**$4,320
**基于 GPU 的数据整理**AWS p4d.24xlarge × 2):
- 费用:$32.77/小时 × 2 = $65.54/小时
- 处理 8TB 耗时:7.5 小时
- **合计**$491.55
**节省**:降低 89%(节省 $3,828
## 支持的数据格式
- **输入**Parquet、JSONL、CSV
- **输出**Parquet(推荐)、JSONL
- **WebDataset**:用于多模态的 TAR 归档
## 使用场景
**生产部署**
- NVIDIA 使用 NeMo Curator 准备 Nemotron-4 训练数据
- 已整理的开源数据集:RedPajama v2、The Pile
## 参考资料
- **[过滤指南](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/nemo-curator/references/filtering.md)** - 30+ 质量过滤器与启发式规则
- **[去重指南](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/nemo-curator/references/deduplication.md)** - 精确、模糊、语义去重方法
## 资源
- **GitHub**https://github.com/NVIDIA/NeMo-Curator ⭐ 500+
- **文档**https://docs.nvidia.com/nemo-framework/user-guide/latest/datacuration/
- **版本**0.4.0+
- **许可证**Apache 2.0
@@ -0,0 +1,452 @@
---
title: "Peft Fine Tuning — 使用 LoRA、QLoRA 及 25+ 种方法对 LLM 进行参数高效微调"
sidebar_label: "Peft Fine Tuning"
description: "使用 LoRA、QLoRA 及 25+ 种方法对 LLM 进行参数高效微调"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Peft Fine Tuning
使用 LoRA、QLoRA 及 25+ 种方法对 LLM 进行参数高效微调(Parameter-efficient fine-tuning)。适用场景:在显存有限的情况下微调大型模型(7B–70B)、需要以极低精度损失训练不足 1% 的参数,或用于多适配器(multi-adapter)服务。HuggingFace 官方库,与 transformers 生态深度集成。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/peft` 安装 |
| 路径 | `optional-skills/mlops/peft` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `peft>=0.13.0`, `transformers>=4.45.0`, `torch>=2.0.0`, `bitsandbytes>=0.43.0` |
| 平台 | linux, macos, windows |
| 标签 | `Fine-Tuning`, `PEFT`, `LoRA`, `QLoRA`, `Parameter-Efficient`, `Adapters`, `Low-Rank`, `Memory Optimization`, `Multi-Adapter` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# PEFT(参数高效微调)
通过 LoRA、QLoRA 及 25+ 种适配器方法,仅训练不足 1% 的参数来微调 LLM。
## 何时使用 PEFT
**在以下情况使用 PEFT/LoRA**
- 在消费级 GPURTX 4090、A100)上微调 7B70B 模型
- 需要训练不足 1% 的参数(6MB 适配器 vs 14GB 完整模型)
- 希望通过多个任务专属适配器快速迭代
- 从单一基础模型部署多个微调变体
**在以下情况使用 QLoRAPEFT + 量化):**
- 在单张 24GB GPU 上微调 70B 模型
- 显存是主要瓶颈
- 可接受相比完整微调约 5% 的质量损失
**在以下情况改用完整微调:**
- 训练小型模型(参数量 < 1B)
- 需要最高质量且有充足算力预算
- 显著的领域偏移需要更新全部权重
## 快速开始
### 安装
```bash
# 基础安装
pip install peft
# 含量化支持(推荐)
pip install peft bitsandbytes
# 完整工具栈
pip install peft transformers accelerate bitsandbytes datasets
```
### LoRA 微调(标准方式)
```python
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
from peft import get_peft_model, LoraConfig, TaskType
from datasets import load_dataset
# 加载基础模型
model_name = "meta-llama/Llama-3.1-8B"
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# LoRA 配置
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16, # 秩(Rank),范围 8-64,越高容量越大
lora_alpha=32, # 缩放因子(通常为 2*r)
lora_dropout=0.05, # 正则化 dropout
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"], # 注意力层
bias="none" # 不训练偏置项
)
# 应用 LoRA
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 输出:trainable params: 13,631,488 || all params: 8,043,307,008 || trainable%: 0.17%
# 准备数据集
dataset = load_dataset("databricks/databricks-dolly-15k", split="train")
def tokenize(example):
text = f"### Instruction:\n{example['instruction']}\n\n### Response:\n{example['response']}"
return tokenizer(text, truncation=True, max_length=512, padding="max_length")
tokenized = dataset.map(tokenize, remove_columns=dataset.column_names)
# 训练
training_args = TrainingArguments(
output_dir="./lora-llama",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
fp16=True,
logging_steps=10,
save_strategy="epoch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized,
data_collator=lambda data: {"input_ids": torch.stack([f["input_ids"] for f in data]),
"attention_mask": torch.stack([f["attention_mask"] for f in data]),
"labels": torch.stack([f["input_ids"] for f in data])}
)
trainer.train()
# 仅保存适配器(6MB vs 16GB
model.save_pretrained("./lora-llama-adapter")
```
### QLoRA 微调(显存高效方式)
```python
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import get_peft_model, LoraConfig, prepare_model_for_kbit_training
# 4-bit 量化配置
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # NormalFloat4(最适合 LLM
bnb_4bit_compute_dtype="bfloat16", # 以 bf16 计算
bnb_4bit_use_double_quant=True # 嵌套量化
)
# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-70B",
quantization_config=bnb_config,
device_map="auto"
)
# 为训练做准备(启用梯度检查点)
model = prepare_model_for_kbit_training(model)
# QLoRA 的 LoRA 配置
lora_config = LoraConfig(
r=64, # 70B 模型使用更高秩
lora_alpha=128,
lora_dropout=0.1,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
# 70B 模型现在可在单张 24GB GPU 上运行!
```
## LoRA 参数选择
### 秩(r)——容量与效率的权衡
| 秩 | 可训练参数量 | 显存 | 质量 | 适用场景 |
|------|-----------------|--------|---------|----------|
| 4 | ~3M | 极低 | 较低 | 简单任务、原型验证 |
| **8** | ~7M | 低 | 良好 | **推荐起始点** |
| **16** | ~14M | 中等 | 更好 | **通用微调** |
| 32 | ~27M | 较高 | 高 | 复杂任务 |
| 64 | ~54M | 高 | 最高 | 领域适配、70B 模型 |
### Alphalora_alpha)——缩放因子
```python
# 经验法则:alpha = 2 * rank
LoraConfig(r=16, lora_alpha=32) # 标准
LoraConfig(r=16, lora_alpha=16) # 保守(学习率效果较低)
LoraConfig(r=16, lora_alpha=64) # 激进(学习率效果较高)
```
### 按架构选择目标模块
```python
# Llama / Mistral / Qwen
target_modules = ["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]
# GPT-2 / GPT-Neo
target_modules = ["c_attn", "c_proj", "c_fc"]
# Falcon
target_modules = ["query_key_value", "dense", "dense_h_to_4h", "dense_4h_to_h"]
# BLOOM
target_modules = ["query_key_value", "dense", "dense_h_to_4h", "dense_4h_to_h"]
# 自动检测所有线性层
target_modules = "all-linear" # PEFT 0.6.0+
```
## 加载与合并适配器
### 加载已训练的适配器
```python
from peft import PeftModel, AutoPeftModelForCausalLM
from transformers import AutoModelForCausalLM
# 方式一:使用 PeftModel 加载
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
model = PeftModel.from_pretrained(base_model, "./lora-llama-adapter")
# 方式二:直接加载(推荐)
model = AutoPeftModelForCausalLM.from_pretrained(
"./lora-llama-adapter",
device_map="auto"
)
```
### 将适配器合并到基础模型
```python
# 合并以用于部署(无适配器开销)
merged_model = model.merge_and_unload()
# 保存合并后的模型
merged_model.save_pretrained("./llama-merged")
tokenizer.save_pretrained("./llama-merged")
# 推送到 Hub
merged_model.push_to_hub("username/llama-finetuned")
```
### 多适配器服务
```python
from peft import PeftModel
# 加载基础模型及第一个适配器
model = AutoPeftModelForCausalLM.from_pretrained("./adapter-task1")
# 加载额外适配器
model.load_adapter("./adapter-task2", adapter_name="task2")
model.load_adapter("./adapter-task3", adapter_name="task3")
# 运行时切换适配器
model.set_adapter("task1") # 使用 task1 适配器
output1 = model.generate(**inputs)
model.set_adapter("task2") # 切换到 task2
output2 = model.generate(**inputs)
# 禁用适配器(使用基础模型)
with model.disable_adapter():
base_output = model.generate(**inputs)
```
## PEFT 方法对比
| 方法 | 可训练参数占比 | 显存 | 速度 | 最适场景 |
|--------|------------|--------|-------|----------|
| **LoRA** | 0.11% | 低 | 快 | 通用微调 |
| **QLoRA** | 0.1–1% | 极低 | 中等 | 显存受限场景 |
| AdaLoRA | 0.11% | 低 | 中等 | 自动秩选择 |
| IA3 | 0.01% | 极小 | 最快 | 少样本适配 |
| Prefix Tuning | 0.1% | 低 | 中等 | 生成控制 |
| Prompt Tuning | 0.001% | 极小 | 快 | 简单任务适配 |
| P-Tuning v2 | 0.1% | 低 | 中等 | NLU 任务 |
### IA3(最少参数)
```python
from peft import IA3Config
ia3_config = IA3Config(
target_modules=["q_proj", "v_proj", "k_proj", "down_proj"],
feedforward_modules=["down_proj"]
)
model = get_peft_model(model, ia3_config)
# 仅训练 0.01% 的参数!
```
### Prefix Tuning
```python
from peft import PrefixTuningConfig
prefix_config = PrefixTuningConfig(
task_type="CAUSAL_LM",
num_virtual_tokens=20, # 前置 token 数量
prefix_projection=True # 使用 MLP 投影
)
model = get_peft_model(model, prefix_config)
```
## 集成模式
### 与 TRLSFTTrainer)集成
```python
from trl import SFTTrainer, SFTConfig
from peft import LoraConfig
lora_config = LoraConfig(r=16, lora_alpha=32, target_modules="all-linear")
trainer = SFTTrainer(
model=model,
args=SFTConfig(output_dir="./output", max_seq_length=512),
train_dataset=dataset,
peft_config=lora_config, # 直接传入 LoRA 配置
)
trainer.train()
```
### 与 AxolotlYAML 配置)集成
```yaml
# axolotl config.yaml
adapter: lora
lora_r: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target_modules:
- q_proj
- v_proj
- k_proj
- o_proj
lora_target_linear: true # 针对所有线性层
```
### 与 vLLM(推理)集成
```python
from vllm import LLM
from vllm.lora.request import LoRARequest
# 加载支持 LoRA 的基础模型
llm = LLM(model="meta-llama/Llama-3.1-8B", enable_lora=True)
# 使用适配器进行推理
outputs = llm.generate(
prompts,
lora_request=LoRARequest("adapter1", 1, "./lora-adapter")
)
```
## 性能基准
### 显存占用(Llama 3.1 8B
| 方法 | GPU 显存 | 可训练参数量 |
|--------|-----------|------------------|
| 完整微调 | 60+ GB | 8B100% |
| LoRA r=16 | 18 GB | 14M0.17% |
| QLoRA r=16 | 6 GB | 14M0.17% |
| IA3 | 16 GB | 800K0.01% |
### 训练速度(A100 80GB
| 方法 | Tokens/秒 | 相对完整微调 |
|--------|-----------|------------|
| 完整微调 | 2,500 | 1x |
| LoRA | 3,200 | 1.3x |
| QLoRA | 2,100 | 0.84x |
### 质量(MMLU 基准)
| 模型 | 完整微调 | LoRA | QLoRA |
|-------|---------|------|-------|
| Llama 2-7B | 45.3 | 44.8 | 44.1 |
| Llama 2-13B | 54.8 | 54.2 | 53.5 |
## 常见问题
### 训练时 CUDA 显存不足(OOM)
```python
# 方案一:启用梯度检查点
model.gradient_checkpointing_enable()
# 方案二:减小批大小 + 增大梯度累积步数
TrainingArguments(
per_device_train_batch_size=1,
gradient_accumulation_steps=16
)
# 方案三:使用 QLoRA
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4")
```
### 适配器未生效
```python
# 验证适配器是否激活
print(model.active_adapters) # 应显示适配器名称
# 检查可训练参数
model.print_trainable_parameters()
# 确保模型处于训练模式
model.train()
```
### 质量下降
```python
# 提高秩
LoraConfig(r=32, lora_alpha=64)
# 针对更多模块
target_modules = "all-linear"
# 使用更多训练数据和更多轮次
TrainingArguments(num_train_epochs=5)
# 降低学习率
TrainingArguments(learning_rate=1e-4)
```
## 最佳实践
1. **从 r=816 开始**,质量不足时再提高
2. **以 alpha = 2 * rank 为起始点**
3. **同时针对注意力层和 MLP 层**以获得最佳质量/效率比
4. **启用梯度检查点**以节省显存
5. **频繁保存适配器**(文件小,便于回滚)
6. **合并前在留出数据上评估**
7. **70B+ 模型在消费级硬件上使用 QLoRA**
## 参考资料
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/peft/references/advanced-usage.md)** — DoRA、LoftQ、秩稳定化、自定义模块
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/peft/references/troubleshooting.md)** — 常见错误、调试、优化
## 资源
- **GitHub**https://github.com/huggingface/peft
- **文档**https://huggingface.co/docs/peft
- **LoRA 论文**arXiv:2106.09685
- **QLoRA 论文**arXiv:2305.14314
- **模型**https://huggingface.co/models?library=peft
@@ -0,0 +1,377 @@
---
title: "Pinecone — 面向生产级 AI 应用的托管向量数据库"
sidebar_label: "Pinecone"
description: "面向生产级 AI 应用的托管向量数据库"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Pinecone
面向生产级 AI 应用的托管向量数据库。全托管、自动扩缩容,支持混合搜索(稠密 + 稀疏向量)、元数据过滤和命名空间。低延迟(&lt;100ms p95)。适用于生产级 RAG、推荐系统或大规模语义搜索。最适合 serverless(无服务器)托管基础设施。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/pinecone` 安装 |
| 路径 | `optional-skills/mlops/pinecone` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `pinecone-client` |
| 平台 | linux, macos, windows |
| 标签 | `RAG`, `Pinecone`, `Vector Database`, `Managed Service`, `Serverless`, `Hybrid Search`, `Production`, `Auto-Scaling`, `Low Latency`, `Recommendations` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# Pinecone - 托管向量数据库
面向生产级 AI 应用的向量数据库。
## 何时使用 Pinecone
**适用场景:**
- 需要托管的 serverless 向量数据库
- 生产级 RAG 应用
- 需要自动扩缩容
- 对低延迟有严格要求(&lt;100ms
- 不想自行管理基础设施
- 需要混合搜索(稠密 + 稀疏向量)
**指标**
- 全托管 SaaS
- 自动扩缩容至数十亿向量
- **p95 延迟 &lt;100ms**
- 99.9% 正常运行时间 SLA
**改用其他方案的场景**
- **Chroma**:自托管、开源
- **FAISS**:离线、纯相似度搜索
- **Weaviate**:自托管、功能更丰富
## 快速开始
### 安装
```bash
pip install pinecone-client
```
### 基本用法
```python
from pinecone import Pinecone, ServerlessSpec
# Initialize
pc = Pinecone(api_key="your-api-key")
# Create index
pc.create_index(
name="my-index",
dimension=1536, # Must match embedding dimension
metric="cosine", # or "euclidean", "dotproduct"
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# Connect to index
index = pc.Index("my-index")
# Upsert vectors
index.upsert(vectors=[
{"id": "vec1", "values": [0.1, 0.2, ...], "metadata": {"category": "A"}},
{"id": "vec2", "values": [0.3, 0.4, ...], "metadata": {"category": "B"}}
])
# Query
results = index.query(
vector=[0.1, 0.2, ...],
top_k=5,
include_metadata=True
)
print(results["matches"])
```
## 核心操作
### 创建索引
```python
# Serverless (recommended)
pc.create_index(
name="my-index",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(
cloud="aws", # or "gcp", "azure"
region="us-east-1"
)
)
# Pod-based (for consistent performance)
from pinecone import PodSpec
pc.create_index(
name="my-index",
dimension=1536,
metric="cosine",
spec=PodSpec(
environment="us-east1-gcp",
pod_type="p1.x1"
)
)
```
### 插入向量(Upsert
```python
# Single upsert
index.upsert(vectors=[
{
"id": "doc1",
"values": [0.1, 0.2, ...], # 1536 dimensions
"metadata": {
"text": "Document content",
"category": "tutorial",
"timestamp": "2025-01-01"
}
}
])
# Batch upsert (recommended)
vectors = [
{"id": f"vec{i}", "values": embedding, "metadata": metadata}
for i, (embedding, metadata) in enumerate(zip(embeddings, metadatas))
]
index.upsert(vectors=vectors, batch_size=100)
```
### 查询向量
```python
# Basic query
results = index.query(
vector=[0.1, 0.2, ...],
top_k=10,
include_metadata=True,
include_values=False
)
# With metadata filtering
results = index.query(
vector=[0.1, 0.2, ...],
top_k=5,
filter={"category": {"$eq": "tutorial"}}
)
# Namespace query
results = index.query(
vector=[0.1, 0.2, ...],
top_k=5,
namespace="production"
)
# Access results
for match in results["matches"]:
print(f"ID: {match['id']}")
print(f"Score: {match['score']}")
print(f"Metadata: {match['metadata']}")
```
### 元数据过滤
```python
# Exact match
filter = {"category": "tutorial"}
# Comparison
filter = {"price": {"$gte": 100}} # $gt, $gte, $lt, $lte, $ne
# Logical operators
filter = {
"$and": [
{"category": "tutorial"},
{"difficulty": {"$lte": 3}}
]
} # Also: $or
# In operator
filter = {"tags": {"$in": ["python", "ml"]}}
```
## 命名空间
```python
# Partition data by namespace
index.upsert(
vectors=[{"id": "vec1", "values": [...]}],
namespace="user-123"
)
# Query specific namespace
results = index.query(
vector=[...],
namespace="user-123",
top_k=5
)
# List namespaces
stats = index.describe_index_stats()
print(stats['namespaces'])
```
## 混合搜索(稠密 + 稀疏向量)
```python
# Upsert with sparse vectors
index.upsert(vectors=[
{
"id": "doc1",
"values": [0.1, 0.2, ...], # Dense vector
"sparse_values": {
"indices": [10, 45, 123], # Token IDs
"values": [0.5, 0.3, 0.8] # TF-IDF scores
},
"metadata": {"text": "..."}
}
])
# Hybrid query
results = index.query(
vector=[0.1, 0.2, ...],
sparse_vector={
"indices": [10, 45],
"values": [0.5, 0.3]
},
top_k=5,
alpha=0.5 # 0=sparse, 1=dense, 0.5=hybrid
)
```
## LangChain 集成
```python
from langchain_pinecone import PineconeVectorStore
from langchain_openai import OpenAIEmbeddings
# Create vector store
vectorstore = PineconeVectorStore.from_documents(
documents=docs,
embedding=OpenAIEmbeddings(),
index_name="my-index"
)
# Query
results = vectorstore.similarity_search("query", k=5)
# With metadata filter
results = vectorstore.similarity_search(
"query",
k=5,
filter={"category": "tutorial"}
)
# As retriever
retriever = vectorstore.as_retriever(search_kwargs={"k": 10})
```
## LlamaIndex 集成
```python
from llama_index.vector_stores.pinecone import PineconeVectorStore
# Connect to Pinecone
pc = Pinecone(api_key="your-key")
pinecone_index = pc.Index("my-index")
# Create vector store
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
# Use in LlamaIndex
from llama_index.core import StorageContext, VectorStoreIndex
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
```
## 索引管理
```python
# List indices
indexes = pc.list_indexes()
# Describe index
index_info = pc.describe_index("my-index")
print(index_info)
# Get index stats
stats = index.describe_index_stats()
print(f"Total vectors: {stats['total_vector_count']}")
print(f"Namespaces: {stats['namespaces']}")
# Delete index
pc.delete_index("my-index")
```
## 删除向量
```python
# Delete by ID
index.delete(ids=["vec1", "vec2"])
# Delete by filter
index.delete(filter={"category": "old"})
# Delete all in namespace
index.delete(delete_all=True, namespace="test")
# Delete entire index
index.delete(delete_all=True)
```
## 最佳实践
1. **使用 serverless** — 自动扩缩容,成本效益高
2. **批量 upsert** — 效率更高(每批 100-200 条)
3. **添加元数据** — 启用过滤功能
4. **使用命名空间** — 按用户/租户隔离数据
5. **监控用量** — 查看 Pinecone 控制台
6. **优化过滤器** — 对频繁过滤的字段建立索引
7. **用免费套餐测试** — 1 个索引,10 万向量免费
8. **使用混合搜索** — 质量更优
9. **设置合适的维度** — 与 embedding 模型匹配
10. **定期备份** — 导出重要数据
## 性能
| 操作 | 延迟 | 备注 |
|-----------|---------|-------|
| Upsert | ~50-100ms | 每批次 |
| 查询(p50) | ~50ms | 取决于索引大小 |
| 查询(p95 | ~100ms | SLA 目标 |
| 元数据过滤 | ~+10-20ms | 额外开销 |
## 定价(截至 2025 年)
**Serverless**
- 每百万读取单元 $0.096
- 每百万写入单元 $0.06
- 每 GB 存储/月 $0.06
**免费套餐**
- 1 个 serverless 索引
- 10 万向量(1536 维)
- 非常适合原型开发
## 资源
- **官网**https://www.pinecone.io
- **文档**https://docs.pinecone.io
- **控制台**https://app.pinecone.io
- **定价**https://www.pinecone.io/pricing
@@ -0,0 +1,365 @@
---
title: "Pytorch Lightning"
sidebar_label: "Pytorch Lightning"
description: "基于 PyTorch 的高层框架,提供 Trainer 类、自动分布式训练(DDP/FSDP/DeepSpeed)、回调系统及极简样板代码"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Pytorch Lightning
基于 PyTorch 的高层框架,提供 Trainer 类、自动分布式训练(DDP/FSDP/DeepSpeed)、回调(callbacks)系统及极简样板代码。同一套代码可从笔记本扩展至超级计算机。适用于希望以内置最佳实践编写整洁训练循环的场景。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/pytorch-lightning` 安装 |
| 路径 | `optional-skills/mlops/pytorch-lightning` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `lightning`, `torch`, `transformers` |
| 平台 | linux, macos, windows |
| 标签 | `PyTorch Lightning`, `Training Framework`, `Distributed Training`, `DDP`, `FSDP`, `DeepSpeed`, `High-Level API`, `Callbacks`, `Best Practices`, `Scalable` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# PyTorch Lightning - 高层训练框架
## 快速开始
PyTorch Lightning 对 PyTorch 代码进行组织,在保持灵活性的同时消除样板代码。
**安装**
```bash
pip install lightning
```
**将 PyTorch 转换为 Lightning**3 步):
```python
import lightning as L
import torch
from torch import nn
from torch.utils.data import DataLoader, Dataset
# Step 1: Define LightningModule (organize your PyTorch code)
class LitModel(L.LightningModule):
def __init__(self, hidden_size=128):
super().__init__()
self.model = nn.Sequential(
nn.Linear(28 * 28, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, 10)
)
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self.model(x)
loss = nn.functional.cross_entropy(y_hat, y)
self.log('train_loss', loss) # Auto-logged to TensorBoard
return loss
def configure_optimizers(self):
return torch.optim.Adam(self.parameters(), lr=1e-3)
# Step 2: Create data
train_loader = DataLoader(train_dataset, batch_size=32)
# Step 3: Train with Trainer (handles everything else!)
trainer = L.Trainer(max_epochs=10, accelerator='gpu', devices=2)
model = LitModel()
trainer.fit(model, train_loader)
```
**就这些!** Trainer 负责处理:
- GPU/TPU/CPU 切换
- 分布式训练(DDP、FSDP、DeepSpeed
- 混合精度(FP16、BF16
- 梯度累积
- 检查点保存
- 日志记录
- 进度条
## 常见工作流
### 工作流 1:从 PyTorch 迁移到 Lightning
**原始 PyTorch 代码**
```python
model = MyModel()
optimizer = torch.optim.Adam(model.parameters())
model.to('cuda')
for epoch in range(max_epochs):
for batch in train_loader:
batch = batch.to('cuda')
optimizer.zero_grad()
loss = model(batch)
loss.backward()
optimizer.step()
```
**Lightning 版本**
```python
class LitModel(L.LightningModule):
def __init__(self):
super().__init__()
self.model = MyModel()
def training_step(self, batch, batch_idx):
loss = self.model(batch) # No .to('cuda') needed!
return loss
def configure_optimizers(self):
return torch.optim.Adam(self.parameters())
# Train
trainer = L.Trainer(max_epochs=10, accelerator='gpu')
trainer.fit(LitModel(), train_loader)
```
**优势**:40+ 行 → 15 行,无需设备管理,自动分布式
### 工作流 2:验证与测试
```python
class LitModel(L.LightningModule):
def __init__(self):
super().__init__()
self.model = MyModel()
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self.model(x)
loss = nn.functional.cross_entropy(y_hat, y)
self.log('train_loss', loss)
return loss
def validation_step(self, batch, batch_idx):
x, y = batch
y_hat = self.model(x)
val_loss = nn.functional.cross_entropy(y_hat, y)
acc = (y_hat.argmax(dim=1) == y).float().mean()
self.log('val_loss', val_loss)
self.log('val_acc', acc)
def test_step(self, batch, batch_idx):
x, y = batch
y_hat = self.model(x)
test_loss = nn.functional.cross_entropy(y_hat, y)
self.log('test_loss', test_loss)
def configure_optimizers(self):
return torch.optim.Adam(self.parameters(), lr=1e-3)
# Train with validation
trainer = L.Trainer(max_epochs=10)
trainer.fit(model, train_loader, val_loader)
# Test
trainer.test(model, test_loader)
```
**自动功能**
- 默认每个 epoch 运行验证
- 指标自动记录到 TensorBoard
- 基于 val_loss 保存最优模型检查点
### 工作流 3:分布式训练(DDP)
```python
# Same code as single GPU!
model = LitModel()
# 8 GPUs with DDP (automatic!)
trainer = L.Trainer(
accelerator='gpu',
devices=8,
strategy='ddp' # Or 'fsdp', 'deepspeed'
)
trainer.fit(model, train_loader)
```
**启动**
```bash
# Single command, Lightning handles the rest
python train.py
```
**无需任何改动**
- 自动数据分发
- 梯度同步
- 多节点支持(只需设置 `num_nodes=2`
### 工作流 4:用于监控的回调(Callbacks)
```python
from lightning.pytorch.callbacks import ModelCheckpoint, EarlyStopping, LearningRateMonitor
# Create callbacks
checkpoint = ModelCheckpoint(
monitor='val_loss',
mode='min',
save_top_k=3,
filename='model-{epoch:02d}-{val_loss:.2f}'
)
early_stop = EarlyStopping(
monitor='val_loss',
patience=5,
mode='min'
)
lr_monitor = LearningRateMonitor(logging_interval='epoch')
# Add to Trainer
trainer = L.Trainer(
max_epochs=100,
callbacks=[checkpoint, early_stop, lr_monitor]
)
trainer.fit(model, train_loader, val_loader)
```
**效果**
- 自动保存最优的 3 个模型
- 若 5 个 epoch 内无改善则提前停止
- 将学习率记录到 TensorBoard
### 工作流 5:学习率调度
```python
class LitModel(L.LightningModule):
# ... (training_step, etc.)
def configure_optimizers(self):
optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
# Cosine annealing
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=100,
eta_min=1e-5
)
return {
'optimizer': optimizer,
'lr_scheduler': {
'scheduler': scheduler,
'interval': 'epoch', # Update per epoch
'frequency': 1
}
}
# Learning rate auto-logged!
trainer = L.Trainer(max_epochs=100)
trainer.fit(model, train_loader)
```
## 何时使用与替代方案对比
**适合使用 PyTorch Lightning 的场景**
- 希望代码整洁、结构清晰
- 需要生产级训练循环
- 在单 GPU、多 GPU、TPU 之间切换
- 希望使用内置回调和日志记录
- 团队协作(标准化结构)
**核心优势**
- **有组织**:将研究代码与工程代码分离
- **自动化**:一行代码启用 DDP、FSDP、DeepSpeed
- **回调**:模块化训练扩展
- **可复现**:样板代码更少 = 更少 bug
- **经过验证**:每月下载量 100 万+,久经考验
**改用其他方案的场景**
- **Accelerate**:对现有代码改动最小,灵活性更高
- **Ray Train**:多节点编排、超参数调优
- **原生 PyTorch**:最大控制权,适合学习目的
- **Keras**TensorFlow 生态系统
## 常见问题
**问题:损失不下降**
检查数据和模型设置:
```python
# Add to training_step
def training_step(self, batch, batch_idx):
if batch_idx == 0:
print(f"Batch shape: {batch[0].shape}")
print(f"Labels: {batch[1]}")
loss = ...
return loss
```
**问题:内存不足**
减小 batch size 或使用梯度累积:
```python
trainer = L.Trainer(
accumulate_grad_batches=4, # Effective batch = batch_size × 4
precision='bf16' # Or 'fp16', reduces memory 50%
)
```
**问题:验证未运行**
确保传入了 val_loader
```python
# WRONG
trainer.fit(model, train_loader)
# CORRECT
trainer.fit(model, train_loader, val_loader)
```
**问题:DDP 意外启动多个进程**
Lightning 会自动检测 GPU。请显式设置 devices
```python
# Test on CPU first
trainer = L.Trainer(accelerator='cpu', devices=1)
# Then GPU
trainer = L.Trainer(accelerator='gpu', devices=1)
```
## 进阶主题
**回调**:参见 [references/callbacks.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/pytorch-lightning/references/callbacks.md),了解 EarlyStopping、ModelCheckpoint、自定义回调及回调钩子(hook)。
**分布式策略**:参见 [references/distributed.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/pytorch-lightning/references/distributed.md),了解 DDP、FSDP、DeepSpeed ZeRO 集成及多节点配置。
**超参数调优**:参见 [references/hyperparameter-tuning.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md),了解与 Optuna、Ray Tune 及 WandB sweeps 的集成。
## 硬件要求
- **CPU**:支持(适合调试)
- **单 GPU**:支持
- **多 GPU**DDP(默认)、FSDP 或 DeepSpeed
- **多节点**DDP、FSDP、DeepSpeed
- **TPU**:支持(8 核)
- **Apple MPS**:支持
**精度选项**
- FP32(默认)
- FP16V100 及较旧 GPU
- BF16A100/H100,推荐)
- FP8H100
## 资源
- 文档:https://lightning.ai/docs/pytorch/stable/
- GitHubhttps://github.com/Lightning-AI/pytorch-lightning ⭐ 29,000+
- 版本:2.5.5+
- 示例:https://github.com/Lightning-AI/pytorch-lightning/tree/master/examples
- Discordhttps://discord.gg/lightning-ai
- 使用者:Kaggle 获奖者、科研实验室、生产团队
@@ -0,0 +1,514 @@
---
title: "Qdrant Vector Search — 用于 RAG 和语义搜索的高性能向量相似度搜索引擎"
sidebar_label: "Qdrant Vector Search"
description: "用于 RAG 和语义搜索的高性能向量相似度搜索引擎"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Qdrant Vector Search
用于 RAG 和语义搜索的高性能向量相似度搜索引擎。适用于构建需要快速最近邻搜索、带过滤的混合搜索,或基于 Rust 高性能的可扩展向量存储的生产级 RAG 系统。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 使用 `hermes skills install official/mlops/qdrant` 安装 |
| 路径 | `optional-skills/mlops/qdrant` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `qdrant-client>=1.12.0` |
| 平台 | linux, macos, windows |
| 标签 | `RAG`, `Vector Search`, `Qdrant`, `Semantic Search`, `Embeddings`, `Similarity Search`, `HNSW`, `Production`, `Distributed` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# Qdrant - 向量相似度搜索引擎
用 Rust 编写的高性能向量数据库,适用于生产级 RAG 和语义搜索。
## 何时使用 Qdrant
**在以下情况下使用 Qdrant**
- 构建需要低延迟的生产级 RAG 系统
- 需要混合搜索(向量 + 元数据过滤)
- 需要通过分片/副本实现水平扩展
- 希望本地部署并完全掌控数据
- 每条记录需要多向量存储(稠密 + 稀疏)
- 构建实时推荐系统
**核心特性:**
- **Rust 驱动**:内存安全,高性能
- **丰富过滤**:在搜索时按任意 payload 字段过滤
- **多向量**:每个点支持稠密、稀疏、多稠密向量
- **量化**:标量、乘积、二值量化,节省内存
- **分布式**Raft 共识、分片、副本
- **REST + gRPC**:两套 API 功能完全对等
**以下情况请使用替代方案:**
- **Chroma**:更简单的配置,嵌入式使用场景
- **FAISS**:追求极致原始速度,研究/批处理场景
- **Pinecone**:完全托管,零运维偏好
- **Weaviate**:偏好 GraphQL,内置向量化器
## 快速开始
### 安装
```bash
# Python 客户端
pip install qdrant-client
# Docker(推荐用于开发)
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
# Docker 持久化存储
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant
```
### 基本用法
```python
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
# 连接到 Qdrant
client = QdrantClient(host="localhost", port=6333)
# 创建集合
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(size=384, distance=Distance.COSINE)
)
# 插入带 payload 的向量
client.upsert(
collection_name="documents",
points=[
PointStruct(
id=1,
vector=[0.1, 0.2, ...], # 384 维向量
payload={"title": "Doc 1", "category": "tech"}
),
PointStruct(
id=2,
vector=[0.3, 0.4, ...],
payload={"title": "Doc 2", "category": "science"}
)
]
)
# 带过滤的搜索
results = client.search(
collection_name="documents",
query_vector=[0.15, 0.25, ...],
query_filter={
"must": [{"key": "category", "match": {"value": "tech"}}]
},
limit=10
)
for point in results:
print(f"ID: {point.id}, Score: {point.score}, Payload: {point.payload}")
```
## 核心概念
### Points(点)— 基本数据单元
```python
from qdrant_client.models import PointStruct
# Point = ID + 向量 + Payload
point = PointStruct(
id=123, # 整数或 UUID 字符串
vector=[0.1, 0.2, 0.3, ...], # 稠密向量
payload={ # 任意 JSON 元数据
"title": "Document title",
"category": "tech",
"timestamp": 1699900000,
"tags": ["python", "ml"]
}
)
# 批量 upsert(推荐)
client.upsert(
collection_name="documents",
points=[point1, point2, point3],
wait=True # 等待索引完成
)
```
### Collections(集合)— 向量容器
```python
from qdrant_client.models import VectorParams, Distance, HnswConfigDiff
# 使用 HNSW 配置创建集合
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(
size=384, # 向量维度
distance=Distance.COSINE # COSINE、EUCLID、DOT、MANHATTAN
),
hnsw_config=HnswConfigDiff(
m=16, # 每个节点的连接数(默认 16)
ef_construct=100, # 构建时精度(默认 100)
full_scan_threshold=10000 # 低于此值切换为暴力搜索
),
on_disk_payload=True # 将 payload 存储在磁盘上
)
# 集合信息
info = client.get_collection("documents")
print(f"Points: {info.points_count}, Vectors: {info.vectors_count}")
```
### 距离度量
| 度量 | 使用场景 | 范围 |
|--------|----------|-------|
| `COSINE` | 文本 embedding、归一化向量 | 0 到 2 |
| `EUCLID` | 空间数据、图像特征 | 0 到 ∞ |
| `DOT` | 推荐系统、非归一化向量 | -∞ 到 ∞ |
| `MANHATTAN` | 稀疏特征、离散数据 | 0 到 ∞ |
## 搜索操作
### 基本搜索
```python
# 简单最近邻搜索
results = client.search(
collection_name="documents",
query_vector=[0.1, 0.2, ...],
limit=10,
with_payload=True,
with_vectors=False # 不返回向量(更快)
)
```
### 带过滤的搜索
```python
from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
# 复杂过滤
results = client.search(
collection_name="documents",
query_vector=query_embedding,
query_filter=Filter(
must=[
FieldCondition(key="category", match=MatchValue(value="tech")),
FieldCondition(key="timestamp", range=Range(gte=1699000000))
],
must_not=[
FieldCondition(key="status", match=MatchValue(value="archived"))
]
),
limit=10
)
# 简写过滤语法
results = client.search(
collection_name="documents",
query_vector=query_embedding,
query_filter={
"must": [
{"key": "category", "match": {"value": "tech"}},
{"key": "price", "range": {"gte": 10, "lte": 100}}
]
},
limit=10
)
```
### 批量搜索
```python
from qdrant_client.models import SearchRequest
# 单次请求中执行多个查询
results = client.search_batch(
collection_name="documents",
requests=[
SearchRequest(vector=[0.1, ...], limit=5),
SearchRequest(vector=[0.2, ...], limit=5, filter={"must": [...]}),
SearchRequest(vector=[0.3, ...], limit=10)
]
)
```
## RAG 集成
### 与 sentence-transformers 集成
```python
from sentence_transformers import SentenceTransformer
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct
# 初始化
encoder = SentenceTransformer("all-MiniLM-L6-v2")
client = QdrantClient(host="localhost", port=6333)
# 创建集合
client.create_collection(
collection_name="knowledge_base",
vectors_config=VectorParams(size=384, distance=Distance.COSINE)
)
# 索引文档
documents = [
{"id": 1, "text": "Python is a programming language", "source": "wiki"},
{"id": 2, "text": "Machine learning uses algorithms", "source": "textbook"},
]
points = [
PointStruct(
id=doc["id"],
vector=encoder.encode(doc["text"]).tolist(),
payload={"text": doc["text"], "source": doc["source"]}
)
for doc in documents
]
client.upsert(collection_name="knowledge_base", points=points)
# RAG 检索
def retrieve(query: str, top_k: int = 5) -> list[dict]:
query_vector = encoder.encode(query).tolist()
results = client.search(
collection_name="knowledge_base",
query_vector=query_vector,
limit=top_k
)
return [{"text": r.payload["text"], "score": r.score} for r in results]
# 在 RAG 流水线中使用
context = retrieve("What is Python?")
prompt = f"Context: {context}\n\nQuestion: What is Python?"
```
### 与 LangChain 集成
```python
from langchain_community.vectorstores import Qdrant
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
vectorstore = Qdrant.from_documents(documents, embeddings, url="http://localhost:6333", collection_name="docs")
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
```
### 与 LlamaIndex 集成
```python
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.core import VectorStoreIndex, StorageContext
vector_store = QdrantVectorStore(client=client, collection_name="llama_docs")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
query_engine = index.as_query_engine()
```
## 多向量支持
### 命名向量(不同 embedding 模型)
```python
from qdrant_client.models import VectorParams, Distance
# 包含多种向量类型的集合
client.create_collection(
collection_name="hybrid_search",
vectors_config={
"dense": VectorParams(size=384, distance=Distance.COSINE),
"sparse": VectorParams(size=30000, distance=Distance.DOT)
}
)
# 插入命名向量
client.upsert(
collection_name="hybrid_search",
points=[
PointStruct(
id=1,
vector={
"dense": dense_embedding,
"sparse": sparse_embedding
},
payload={"text": "document text"}
)
]
)
# 搜索指定向量
results = client.search(
collection_name="hybrid_search",
query_vector=("dense", query_dense), # 指定使用哪个向量
limit=10
)
```
### 稀疏向量(BM25、SPLADE
```python
from qdrant_client.models import SparseVectorParams, SparseIndexParams, SparseVector
# 包含稀疏向量的集合
client.create_collection(
collection_name="sparse_search",
vectors_config={},
sparse_vectors_config={"text": SparseVectorParams(index=SparseIndexParams(on_disk=False))}
)
# 插入稀疏向量
client.upsert(
collection_name="sparse_search",
points=[PointStruct(id=1, vector={"text": SparseVector(indices=[1, 5, 100], values=[0.5, 0.8, 0.2])}, payload={"text": "document"})]
)
```
## 量化(内存优化)
```python
from qdrant_client.models import ScalarQuantization, ScalarQuantizationConfig, ScalarType
# 标量量化(内存减少 4 倍)
client.create_collection(
collection_name="quantized",
vectors_config=VectorParams(size=384, distance=Distance.COSINE),
quantization_config=ScalarQuantization(
scalar=ScalarQuantizationConfig(
type=ScalarType.INT8,
quantile=0.99, # 裁剪异常值
always_ram=True # 将量化数据保留在 RAM 中
)
)
)
# 带重新评分的搜索
results = client.search(
collection_name="quantized",
query_vector=query,
search_params={"quantization": {"rescore": True}}, # 对 top 结果重新评分
limit=10
)
```
## Payload 索引
```python
from qdrant_client.models import PayloadSchemaType
# 创建 payload 索引以加速过滤
client.create_payload_index(
collection_name="documents",
field_name="category",
field_schema=PayloadSchemaType.KEYWORD
)
client.create_payload_index(
collection_name="documents",
field_name="timestamp",
field_schema=PayloadSchemaType.INTEGER
)
# 索引类型:KEYWORD、INTEGER、FLOAT、GEO、TEXT(全文)、BOOL
```
## 生产部署
### Qdrant Cloud
```python
from qdrant_client import QdrantClient
# 连接到 Qdrant Cloud
client = QdrantClient(
url="https://your-cluster.cloud.qdrant.io",
api_key="your-api-key"
)
```
### 性能调优
```python
# 优化搜索速度(更高召回率)
client.update_collection(
collection_name="documents",
hnsw_config=HnswConfigDiff(ef_construct=200, m=32)
)
# 优化索引速度(批量加载)
client.update_collection(
collection_name="documents",
optimizer_config={"indexing_threshold": 20000}
)
```
## 最佳实践
1. **批量操作** — 使用批量 upsert/search 提升效率
2. **Payload 索引** — 对过滤中使用的字段建立索引
3. **量化** — 对大型集合(>100 万向量)启用量化
4. **分片** — 对超过 1000 万向量的集合使用分片
5. **磁盘存储** — 对大型 payload 启用 `on_disk_payload`
6. **连接池** — 复用客户端实例
## 常见问题
**带过滤的搜索速度慢:**
```python
# 为过滤字段创建 payload 索引
client.create_payload_index(
collection_name="docs",
field_name="category",
field_schema=PayloadSchemaType.KEYWORD
)
```
**内存不足:**
```python
# 启用量化和磁盘存储
client.create_collection(
collection_name="large_collection",
vectors_config=VectorParams(size=384, distance=Distance.COSINE),
quantization_config=ScalarQuantization(...),
on_disk_payload=True
)
```
**连接问题:**
```python
# 使用超时和重试
client = QdrantClient(
host="localhost",
port=6333,
timeout=30,
prefer_grpc=True # gRPC 性能更佳
)
```
## 参考资料
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/qdrant/references/advanced-usage.md)** — 分布式模式、混合搜索、推荐系统
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/qdrant/references/troubleshooting.md)** — 常见问题、调试、性能调优
## 资源
- **GitHub**https://github.com/qdrant/qdrant22k+ stars
- **文档**https://qdrant.tech/documentation/
- **Python 客户端**https://github.com/qdrant/qdrant-client
- **Cloud**https://cloud.qdrant.io
- **版本**1.12.0+
- **许可证**Apache 2.0
@@ -0,0 +1,407 @@
---
title: "稀疏自编码器训练"
sidebar_label: "稀疏自编码器训练"
description: "提供使用 SAELens 训练和分析稀疏自编码器(SAE)的指导,将神经网络激活分解为可解释特征"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# 稀疏自编码器训练
提供使用 SAELens 训练和分析稀疏自编码器(SAE)的指导,将神经网络激活分解为可解释特征。适用于发现可解释特征、分析叠加现象,或研究语言模型中的单义性表示。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/saelens` 安装 |
| 路径 | `optional-skills/mlops/saelens` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `sae-lens>=6.0.0`, `transformer-lens>=2.0.0`, `torch>=2.0.0` |
| 平台 | linux, macos, windows |
| 标签 | `Sparse Autoencoders`, `SAE`, `Mechanistic Interpretability`, `Feature Discovery`, `Superposition` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# SAELens:用于机制可解释性的稀疏自编码器
SAELens 是训练和分析稀疏自编码器(SAE)的主要库。SAE 是一种将多义性神经网络激活分解为稀疏、可解释特征的技术,基于 Anthropic 在单义性方面的开创性研究。
**GitHub**[jbloomAus/SAELens](https://github.com/jbloomAus/SAELens)1,100+ stars
## 问题背景:多义性与叠加(Superposition
神经网络中的单个神经元是**多义性**的——它们在多种语义不同的上下文中激活。这是因为模型使用**叠加**(superposition)来表示比神经元数量更多的特征,从而使可解释性变得困难。
**SAE 的解决方案**:将密集激活分解为稀疏的单义性特征——对于任意给定输入,通常只有少量特征激活,且每个特征对应一个可解释的概念。
## 何时使用 SAELens
**在以下情况下使用 SAELens**
- 发现模型激活中的可解释特征
- 理解模型学到了哪些概念
- 研究叠加现象和特征几何结构
- 执行基于特征的引导(steering)或消融(ablation
- 分析安全相关特征(欺骗、偏见、有害内容)
**在以下情况下考虑替代方案:**
- 需要基础激活分析 → 直接使用 **TransformerLens**
- 需要因果干预实验 → 使用 **pyvene** 或 **TransformerLens**
- 需要生产环境引导 → 考虑直接激活工程
## 安装
```bash
pip install sae-lens
```
要求:Python 3.10+transformer-lens>=2.0.0
## 核心概念
### SAE 学到了什么
SAE 通过稀疏瓶颈重建模型激活:
```
Input Activation → Encoder → Sparse Features → Decoder → Reconstructed Activation
(d_model) ↓ (d_sae >> d_model) ↓ (d_model)
sparsity reconstruction
penalty loss
```
**损失函数**`MSE(original, reconstructed) + L1_coefficient × L1(features)`
### 关键验证(Anthropic 研究)
在《Towards Monosemanticity》中,人工评估者发现 **70% 的 SAE 特征具有真正的可解释性**。发现的特征包括:
- DNA 序列、法律语言、HTTP 请求
- 希伯来文本、营养声明、代码语法
- 情感、命名实体、语法结构
## 工作流 1:加载和分析预训练 SAE
### 步骤说明
```python
from transformer_lens import HookedTransformer
from sae_lens import SAE
# 1. 加载模型和预训练 SAE
model = HookedTransformer.from_pretrained("gpt2-small", device="cuda")
sae, cfg_dict, sparsity = SAE.from_pretrained(
release="gpt2-small-res-jb",
sae_id="blocks.8.hook_resid_pre",
device="cuda"
)
# 2. 获取模型激活
tokens = model.to_tokens("The capital of France is Paris")
_, cache = model.run_with_cache(tokens)
activations = cache["resid_pre", 8] # [batch, pos, d_model]
# 3. 编码为 SAE 特征
sae_features = sae.encode(activations) # [batch, pos, d_sae]
print(f"Active features: {(sae_features > 0).sum()}")
# 4. 找出每个位置的顶部特征
for pos in range(tokens.shape[1]):
top_features = sae_features[0, pos].topk(5)
token = model.to_str_tokens(tokens[0, pos:pos+1])[0]
print(f"Token '{token}': features {top_features.indices.tolist()}")
# 5. 重建激活
reconstructed = sae.decode(sae_features)
reconstruction_error = (activations - reconstructed).norm()
```
### 可用预训练 SAE
| Release | 模型 | 层 |
|---------|-------|--------|
| `gpt2-small-res-jb` | GPT-2 Small | 多个残差流 |
| `gemma-2b-res` | Gemma 2B | 残差流 |
| HuggingFace 上的各类 SAE | 搜索标签 `saelens` | 各种 |
### 检查清单
- [ ] 使用 TransformerLens 加载模型
- [ ] 为目标层加载匹配的 SAE
- [ ] 将激活编码为稀疏特征
- [ ] 识别每个 token 的顶部激活特征
- [ ] 验证重建质量
## 工作流 2:训练自定义 SAE
### 步骤说明
```python
from sae_lens import SAE, LanguageModelSAERunnerConfig, SAETrainingRunner
# 1. 配置训练
cfg = LanguageModelSAERunnerConfig(
# 模型
model_name="gpt2-small",
hook_name="blocks.8.hook_resid_pre",
hook_layer=8,
d_in=768, # 模型维度
# SAE 架构
architecture="standard", # 或 "gated"、"topk"
d_sae=768 * 8, # 扩展因子为 8
activation_fn="relu",
# 训练
lr=4e-4,
l1_coefficient=8e-5, # 稀疏性惩罚
l1_warm_up_steps=1000,
train_batch_size_tokens=4096,
training_tokens=100_000_000,
# 数据
dataset_path="monology/pile-uncopyrighted",
context_size=128,
# 日志
log_to_wandb=True,
wandb_project="sae-training",
# 检查点
checkpoint_path="checkpoints",
n_checkpoints=5,
)
# 2. 训练
trainer = SAETrainingRunner(cfg)
sae = trainer.run()
# 3. 评估
print(f"L0 (avg active features): {trainer.metrics['l0']}")
print(f"CE Loss Recovered: {trainer.metrics['ce_loss_score']}")
```
### 关键超参数
| 参数 | 典型值 | 效果 |
|-----------|---------------|--------|
| `d_sae` | 416× d_model | 特征更多,容量更大 |
| `l1_coefficient` | 5e-5 到 1e-4 | 越高 = 越稀疏,精度越低 |
| `lr` | 1e-4 到 1e-3 | 标准优化器学习率 |
| `l1_warm_up_steps` | 5002000 | 防止特征早期死亡 |
### 评估指标
| 指标 | 目标值 | 含义 |
|--------|--------|---------|
| **L0** | 50200 | 每个 token 的平均激活特征数 |
| **CE Loss Score** | 80–95% | 相对原始模型恢复的交叉熵 |
| **Dead Features** | &lt;5% | 从不激活的特征比例 |
| **Explained Variance** | >90% | 重建质量 |
### 检查清单
- [ ] 选择目标层和 hook 点
- [ ] 设置扩展因子(d_sae = 416× d_model
- [ ] 调整 L1 系数以获得期望的稀疏度
- [ ] 启用 L1 预热以防止特征死亡
- [ ] 训练期间监控指标(W&B)
- [ ] 验证 L0 和 CE loss 恢复情况
- [ ] 检查死亡特征比例
## 工作流 3:特征分析与引导
### 分析单个特征
```python
from transformer_lens import HookedTransformer
from sae_lens import SAE
import torch
model = HookedTransformer.from_pretrained("gpt2-small", device="cuda")
sae, _, _ = SAE.from_pretrained(
release="gpt2-small-res-jb",
sae_id="blocks.8.hook_resid_pre",
device="cuda"
)
# 找出激活特定特征的内容
feature_idx = 1234
test_texts = [
"The scientist conducted an experiment",
"I love chocolate cake",
"The code compiles successfully",
"Paris is beautiful in spring",
]
for text in test_texts:
tokens = model.to_tokens(text)
_, cache = model.run_with_cache(tokens)
features = sae.encode(cache["resid_pre", 8])
activation = features[0, :, feature_idx].max().item()
print(f"{activation:.3f}: {text}")
```
### 特征引导(Feature Steering
```python
def steer_with_feature(model, sae, prompt, feature_idx, strength=5.0):
"""将 SAE 特征方向添加到残差流。"""
tokens = model.to_tokens(prompt)
# 从解码器获取特征方向
feature_direction = sae.W_dec[feature_idx] # [d_model]
def steering_hook(activation, hook):
# 在所有位置添加缩放后的特征方向
activation += strength * feature_direction
return activation
# 带引导的生成
output = model.generate(
tokens,
max_new_tokens=50,
fwd_hooks=[("blocks.8.hook_resid_pre", steering_hook)]
)
return model.to_string(output[0])
```
### 特征归因(Feature Attribution
```python
# 哪些特征对特定输出影响最大?
tokens = model.to_tokens("The capital of France is")
_, cache = model.run_with_cache(tokens)
# 获取最后位置的特征
features = sae.encode(cache["resid_pre", 8])[0, -1] # [d_sae]
# 计算每个特征的 logit 归因
# 特征贡献 = 特征激活 × 解码器权重 × 反嵌入
W_dec = sae.W_dec # [d_sae, d_model]
W_U = model.W_U # [d_model, vocab]
# 对 "Paris" logit 的贡献
paris_token = model.to_single_token(" Paris")
feature_contributions = features * (W_dec @ W_U[:, paris_token])
top_features = feature_contributions.topk(10)
print("Top features for 'Paris' prediction:")
for idx, val in zip(top_features.indices, top_features.values):
print(f" Feature {idx.item()}: {val.item():.3f}")
```
## 常见问题与解决方案
### 问题:死亡特征比例过高
```python
# 错误:无预热,特征早期死亡
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4,
l1_warm_up_steps=0, # 不推荐!
)
# 正确:预热 L1 惩罚
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=8e-5,
l1_warm_up_steps=1000, # 逐步增加
use_ghost_grads=True, # 复活死亡特征
)
```
### 问题:重建效果差(CE 恢复率低)
```python
# 降低稀疏性惩罚
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=5e-5, # 越低 = 重建越好
d_sae=768 * 16, # 更大容量
)
```
### 问题:特征不可解释
```python
# 提高稀疏性(更高的 L1
cfg = LanguageModelSAERunnerConfig(
l1_coefficient=1e-4, # 越高 = 越稀疏,可解释性越强
)
# 或使用 TopK 架构
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn_kwargs={"k": 50}, # 恰好 50 个激活特征
)
```
### 问题:训练时内存错误
```python
cfg = LanguageModelSAERunnerConfig(
train_batch_size_tokens=2048, # 减小批次大小
store_batch_size_prompts=4, # 缓冲区中更少的 prompt
n_batches_in_buffer=8, # 更小的激活缓冲区
)
```
## 与 Neuronpedia 集成
在 [neuronpedia.org](https://neuronpedia.org) 浏览预训练 SAE 特征:
```python
# 特征通过 SAE ID 索引
# 示例:gpt2-small 第 8 层特征 1234
# → neuronpedia.org/gpt2-small/8-res-jb/1234
```
## 关键类参考
| 类 | 用途 |
|-------|---------|
| `SAE` | 稀疏自编码器模型 |
| `LanguageModelSAERunnerConfig` | 训练配置 |
| `SAETrainingRunner` | 训练循环管理器 |
| `ActivationsStore` | 激活收集与批处理 |
| `HookedSAETransformer` | TransformerLens + SAE 集成 |
## 参考文档
详细的 API 文档、教程和高级用法,请参阅 `references/` 文件夹:
| 文件 | 内容 |
|------|----------|
| [references/README.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/saelens/references/README.md) | 概述与快速入门指南 |
| [references/api.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/saelens/references/api.md) | SAE、TrainingSAE、配置的完整 API 参考 |
| [references/tutorials.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/saelens/references/tutorials.md) | 训练、分析、引导的分步教程 |
## 外部资源
### 教程
- [基础加载与分析](https://github.com/jbloomAus/SAELens/blob/main/tutorials/basic_loading_and_analysing.ipynb)
- [训练稀疏自编码器](https://github.com/jbloomAus/SAELens/blob/main/tutorials/training_a_sparse_autoencoder.ipynb)
- [ARENA SAE 课程](https://www.lesswrong.com/posts/LnHowHgmrMbWtpkxx/intro-to-superposition-and-sparse-autoencoders-colab)
### 论文
- [Towards Monosemanticity](https://transformer-circuits.pub/2023/monosemantic-features) — Anthropic2023
- [Scaling Monosemanticity](https://transformer-circuits.pub/2024/scaling-monosemanticity/) — Anthropic2024
- [Sparse Autoencoders Find Highly Interpretable Features](https://arxiv.org/abs/2309.08600) — Cunningham et al.ICLR 2024
### 官方文档
- [SAELens 文档](https://jbloomaus.github.io/SAELens/)
- [Neuronpedia](https://neuronpedia.org) — 特征浏览器
## SAE 架构
| 架构 | 描述 | 适用场景 |
|--------------|-------------|----------|
| **Standard** | ReLU + L1 惩罚 | 通用 |
| **Gated** | 学习门控机制 | 更好的稀疏性控制 |
| **TopK** | 恰好 K 个激活特征 | 一致的稀疏性 |
```python
# TopK SAE(恰好 50 个特征激活)
cfg = LanguageModelSAERunnerConfig(
architecture="topk",
activation_fn="topk",
activation_fn_kwargs={"k": 50},
)
```
@@ -0,0 +1,237 @@
---
title: "Simpo 训练 — 用于 LLM 对齐的简单偏好优化"
sidebar_label: "Simpo 训练"
description: "用于 LLM 对齐的简单偏好优化"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Simpo 训练
用于 LLM 对齐的简单偏好优化(Simple Preference Optimization)。无需参考模型的 DPO 替代方案,性能更优(在 AlpacaEval 2.0 上提升 +6.4 分)。无需参考模型,比 DPO 更高效。当需要比 DPO/PPO 更简单、更快速的训练时,可用于偏好对齐。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/simpo` 安装 |
| 路径 | `optional-skills/mlops/simpo` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `torch`, `transformers`, `datasets`, `trl`, `accelerate` |
| 平台 | linux, macos, windows |
| 标签 | `Post-Training`, `SimPO`, `Preference Optimization`, `Alignment`, `DPO Alternative`, `Reference-Free`, `LLM Alignment`, `Efficient Training` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# SimPO - 简单偏好优化
## 快速开始
SimPO 是一种无需参考模型的偏好优化方法,性能优于 DPO。
**安装**
```bash
# Create environment
conda create -n simpo python=3.10 && conda activate simpo
# Install PyTorch 2.2.2
# Visit: https://pytorch.org/get-started/locally/
# Install alignment-handbook
git clone https://github.com/huggingface/alignment-handbook.git
cd alignment-handbook
python -m pip install .
# Install Flash Attention 2
python -m pip install flash-attn --no-build-isolation
```
**训练**Mistral 7B):
```bash
ACCELERATE_LOG_LEVEL=info accelerate launch \
--config_file accelerate_configs/deepspeed_zero3.yaml \
scripts/run_simpo.py \
training_configs/mistral-7b-base-simpo.yaml
```
## 常见工作流
### 工作流 1:从基础模型训练(Mistral 7B)
**配置文件**`mistral-7b-base-simpo.yaml`):
```yaml
# Model
model_name_or_path: mistralai/Mistral-7B-v0.1
torch_dtype: bfloat16
# Dataset
dataset_mixer:
HuggingFaceH4/ultrafeedback_binarized: 1.0
dataset_splits:
- train_prefs
- test_prefs
# SimPO hyperparameters
beta: 2.0 # Reward scaling (2.0-10.0)
gamma_beta_ratio: 0.5 # Target margin (0-1)
loss_type: sigmoid # sigmoid or hinge
sft_weight: 0.0 # Optional SFT regularization
# Training
learning_rate: 5e-7 # Critical: 3e-7 to 1e-6
num_train_epochs: 1
per_device_train_batch_size: 1
gradient_accumulation_steps: 8
# Output
output_dir: ./outputs/mistral-7b-simpo
```
**启动训练**
```bash
accelerate launch --config_file accelerate_configs/deepspeed_zero3.yaml \
scripts/run_simpo.py training_configs/mistral-7b-base-simpo.yaml
```
### 工作流 2:微调指令模型(Llama 3 8B)
**配置文件**`llama3-8b-instruct-simpo.yaml`):
```yaml
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
dataset_mixer:
argilla/ultrafeedback-binarized-preferences-cleaned: 1.0
beta: 2.5
gamma_beta_ratio: 0.5
learning_rate: 5e-7
sft_weight: 0.1 # Add SFT loss to preserve capabilities
num_train_epochs: 1
per_device_train_batch_size: 2
gradient_accumulation_steps: 4
output_dir: ./outputs/llama3-8b-simpo
```
**启动**
```bash
accelerate launch --config_file accelerate_configs/deepspeed_zero3.yaml \
scripts/run_simpo.py training_configs/llama3-8b-instruct-simpo.yaml
```
### 工作流 3:推理密集型任务(较低学习率)
**适用于数学/代码任务**
```yaml
model_name_or_path: deepseek-ai/deepseek-math-7b-base
dataset_mixer:
argilla/distilabel-math-preference-dpo: 1.0
beta: 5.0 # Higher for stronger signal
gamma_beta_ratio: 0.7 # Larger margin
learning_rate: 3e-7 # Lower LR for reasoning
sft_weight: 0.0
num_train_epochs: 1
per_device_train_batch_size: 1
gradient_accumulation_steps: 16
```
## 何时使用及替代方案
**适合使用 SimPO 的场景**
- 希望比 DPO 训练更简单(无需参考模型)
- 拥有偏好数据(chosen/rejected 对)
- 需要比 DPO 更好的性能
- 计算资源有限
- 单节点训练即可满足需求
**算法选择**
- **SimPO**:最简单、性能最优、无需参考模型
- **DPO**:需要参考模型基线,更为保守
- **PPO**:最大控制度,需要奖励模型,配置复杂
- **GRPO**:内存高效的 RL,无需 critic
**改用其他方案的场景**
- **OpenRLHF**:多节点分布式训练,PPO/GRPO
- **TRL**:需要在单一框架中使用多种方法
- **DPO**:需要建立已有基线对比
## 常见问题
**问题:损失发散**
降低学习率:
```yaml
learning_rate: 3e-7 # Reduce from 5e-7
```
降低 beta
```yaml
beta: 1.0 # Reduce from 2.0
```
**问题:模型遗忘原有能力**
添加 SFT 正则化:
```yaml
sft_weight: 0.1 # Add SFT loss component
```
**问题:偏好分离效果差**
提高 beta 和 margin
```yaml
beta: 5.0 # Increase from 2.0
gamma_beta_ratio: 0.8 # Increase from 0.5
```
**问题:训练时显存不足(OOM**
减小批次大小:
```yaml
per_device_train_batch_size: 1
gradient_accumulation_steps: 16 # Maintain effective batch
```
启用梯度检查点:
```yaml
gradient_checkpointing: true
```
## 进阶主题
**损失函数**:参见 [references/loss-functions.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/simpo/references/loss-functions.md),了解 sigmoid 与 hinge 损失、数学公式及各自适用场景。
**超参数调优**:参见 [references/hyperparameters.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/simpo/references/hyperparameters.md),了解 beta、gamma、学习率选择指南及针对不同模型规模的建议。
**数据集准备**:参见 [references/datasets.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/simpo/references/datasets.md),了解偏好数据格式、质量过滤及自定义数据集创建方法。
## 硬件要求
- **GPU**:推荐 NVIDIA A100/H100
- **显存**
- 7B 模型:1× A100 40GBDeepSpeed ZeRO-3
- 8B 模型:2× A100 40GB
- 70B 模型:8× A100 80GB
- **单节点**DeepSpeed ZeRO-3 即可满足
- **混合精度**:推荐 BF16
**内存优化**
- DeepSpeed ZeRO-3(默认配置)
- 梯度检查点
- Flash Attention 2
## 资源
- 论文:https://arxiv.org/abs/2405.14734NeurIPS 2024
- GitHubhttps://github.com/princeton-nlp/SimPO
- 模型:https://huggingface.co/princeton-nlp
- Alignment Handbookhttps://github.com/huggingface/alignment-handbook
@@ -0,0 +1,486 @@
---
title: "Slime Rl Training — 使用 slimeMegatron+SGLang 框架)进行 LLM RL 后训练的指导"
sidebar_label: "Slime Rl Training"
description: "使用 slimeMegatron+SGLang 框架)进行 LLM RL 后训练的指导"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Slime Rl Training
使用 slimeMegatron+SGLang 框架)进行 LLM RL(强化学习)后训练的指导。适用于训练 GLM 模型、实现自定义数据生成工作流,或需要 Megatron-LM 紧密集成以进行 RL 扩展的场景。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/slime` 安装 |
| 路径 | `optional-skills/mlops/slime` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `sglang-router>=0.2.3`, `ray`, `torch>=2.0.0`, `transformers>=4.40.0` |
| 平台 | linux, macos |
| 标签 | `Reinforcement Learning`, `Megatron-LM`, `SGLang`, `GRPO`, `Post-Training`, `GLM` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# slime:面向 RL 扩展的 LLM 后训练框架
slime 是清华大学 THUDM 团队开发的 LLM 后训练框架,为 GLM-4.5、GLM-4.6 和 GLM-4.7 提供支持。它将 Megatron-LM(用于训练)与 SGLang(用于高吞吐量 rollout 生成)相连接。
## 何时使用 slime
**在以下情况下选择 slime**
- 需要 Megatron-LM 原生训练配合 SGLang 推理
- 需要带有灵活数据缓冲区的自定义数据生成工作流
- 训练 GLM、Qwen3、DeepSeek V3 或 Llama 3 模型
- 需要具有生产级支持(Z.ai)的研究级框架
**在以下情况下考虑替代方案:**
- 需要企业级稳定性功能 → 使用 **miles**
- 需要灵活的后端切换 → 使用 **verl**
- 需要 PyTorch 原生抽象 → 使用 **torchforge**
## 核心特性
- **训练**Megatron-LM,支持完整并行(TP、PP、DP、SP)
- **Rollout**:基于 SGLang 的高吞吐量生成,带 router
- **数据缓冲区**:灵活的 prompt 管理与样本存储
- **模型**GLM-4.x、Qwen3、DeepSeek V3/R1、Llama 3
## 架构概览
<!-- ascii-guard-ignore -->
```
┌─────────────────────────────────────────────────────────┐
│ Data Buffer │
│ - Prompt initialization and management │
│ - Custom data generation and filtering │
│ - Rollout sample storage │
└─────────────┬───────────────────────────┬───────────────┘
│ │
┌─────────────▼───────────┐ ┌─────────────▼───────────────┐
│ Training (Megatron-LM) │ │ Rollout (SGLang + Router) │
│ - Actor model training │ │ - Response generation │
│ - Critic (optional) │ │ - Reward/verifier output │
│ - Weight sync to rollout│ │ - Multi-turn support │
└─────────────────────────┘ └─────────────────────────────┘
```
<!-- ascii-guard-ignore-end -->
## 安装
```bash
# 推荐:Docker
docker pull slimerl/slime:latest
docker run --rm --gpus all --ipc=host --shm-size=16g \
-it slimerl/slime:latest /bin/bash
# 容器内
cd /root/slime && pip install -e . --no-deps
```
### 从源码安装
```bash
git clone https://github.com/THUDM/slime.git
cd slime
pip install -r requirements.txt
pip install -e .
```
## 快速开始:GRPO 训练
```bash
# 加载模型配置
source scripts/models/qwen3-4B.sh
# 启动训练
python train.py \
--actor-num-nodes 1 \
--actor-num-gpus-per-node 4 \
--rollout-num-gpus 4 \
--advantage-estimator grpo \
--use-kl-loss --kl-loss-coef 0.001 \
--rollout-batch-size 32 \
--n-samples-per-prompt 8 \
--global-batch-size 256 \
--num-rollout 3000 \
--prompt-data /path/to/data.jsonl \
${MODEL_ARGS[@]} ${CKPT_ARGS[@]}
```
---
## 工作流 1:标准 GRPO 训练
使用此工作流通过组相对优势(group-relative advantages)训练推理模型。
### 前置条件清单
- [ ] Docker 环境,或已安装 Megatron-LM + SGLang
- [ ] 模型检查点(HuggingFace 或 Megatron 格式)
- [ ] JSONL 格式的训练数据
### 第一步:准备数据
```python
# data.jsonl 格式
{"prompt": "What is 2 + 2?", "label": "4"}
{"prompt": "Solve: 3x = 12", "label": "x = 4"}
```
或使用对话格式:
```python
{
"prompt": [
{"role": "system", "content": "You are a math tutor."},
{"role": "user", "content": "What is 15 + 27?"}
],
"label": "42"
}
```
### 第二步:配置模型
选择预配置的模型脚本:
```bash
# 列出可用模型
ls scripts/models/
# glm4-9B.sh, qwen3-4B.sh, qwen3-30B-A3B.sh, deepseek-v3.sh, llama3-8B.sh, ...
# 加载你的模型
source scripts/models/qwen3-4B.sh
```
### 第三步:启动训练
```bash
python train.py \
--actor-num-nodes 1 \
--actor-num-gpus-per-node 8 \
--rollout-num-gpus 8 \
--advantage-estimator grpo \
--use-kl-loss \
--kl-loss-coef 0.001 \
--prompt-data /path/to/train.jsonl \
--input-key prompt \
--label-key label \
--apply-chat-template \
--rollout-batch-size 32 \
--n-samples-per-prompt 8 \
--global-batch-size 256 \
--num-rollout 3000 \
--save-interval 100 \
--eval-interval 50 \
${MODEL_ARGS[@]}
```
### 第四步:监控训练
- [ ] 查看 TensorBoard`tensorboard --logdir outputs/`
- [ ] 确认奖励曲线持续上升
- [ ] 监控各节点 GPU 利用率
---
## 工作流 2:异步训练
使用异步模式通过重叠 rollout 与训练来提高吞吐量。
### 何时使用异步模式
- 大型模型生成时间较长
- 同步模式下 GPU 空闲时间较多
- 有足够内存用于缓冲
### 启动异步训练
```bash
python train_async.py \
--actor-num-nodes 1 \
--actor-num-gpus-per-node 8 \
--rollout-num-gpus 8 \
--advantage-estimator grpo \
--async-buffer-size 4 \
--prompt-data /path/to/train.jsonl \
${MODEL_ARGS[@]}
```
### 异步专用参数
```bash
--async-buffer-size 4 # 缓冲的 rollout 数量
--update-weights-interval 2 # 每 N 次 rollout 同步一次权重
```
---
## 工作流 3:多轮 Agentic 训练
使用此工作流训练具备工具调用或多步推理能力的 agent。
### 前置条件
- [ ] 用于多轮逻辑的自定义 generate 函数
- [ ] 工具/环境接口
### 第一步:定义自定义 Generate 函数
```python
# custom_generate.py
async def custom_generate(args, samples, evaluation=False):
"""带工具调用的多轮生成。"""
for sample in samples:
conversation = sample.prompt
for turn in range(args.max_turns):
# 生成响应
response = await generate_single(conversation)
# 检查工具调用
tool_call = extract_tool_call(response)
if tool_call:
tool_result = execute_tool(tool_call)
conversation.append({"role": "assistant", "content": response})
conversation.append({"role": "tool", "content": tool_result})
else:
break
sample.response = response
sample.reward = compute_reward(sample)
return samples
```
### 第二步:使用自定义函数启动
```bash
python train.py \
--custom-generate-function-path custom_generate.py \
--max-turns 5 \
--prompt-data /path/to/agent_data.jsonl \
${MODEL_ARGS[@]}
```
完整的多轮搜索示例请参见 `examples/search-r1/`
---
## 配置参考
### 三类参数
slime 使用三种类型的参数:
**1. Megatron 参数**(直接传入):
```bash
--tensor-model-parallel-size 2
--pipeline-model-parallel-size 1
--num-layers 32
--hidden-size 4096
```
**2. SGLang 参数**(以 `--sglang-` 为前缀):
```bash
--sglang-mem-fraction-static 0.8
--sglang-context-length 8192
--sglang-log-level INFO
```
**3. slime 参数**
```bash
# 资源分配
--actor-num-nodes 1
--actor-num-gpus-per-node 8
--rollout-num-gpus 8
--colocate # 训练与推理共享 GPU
# 数据
--prompt-data /path/to/data.jsonl
--input-key prompt
--label-key label
# 训练循环
--num-rollout 3000
--rollout-batch-size 32
--n-samples-per-prompt 8
--global-batch-size 256
# 算法
--advantage-estimator grpo # 或:gspo, ppo, reinforce_plus_plus
--use-kl-loss
--kl-loss-coef 0.001
```
### 关键约束
```
rollout_batch_size × n_samples_per_prompt = global_batch_size × num_steps_per_rollout
```
示例:32 × 8 = 256 × 1
---
## 数据缓冲区系统
slime 的数据缓冲区支持灵活的数据管理:
### 基础数据源
```python
class RolloutDataSource:
def get_samples(self, num_samples):
"""从数据集中获取 prompt。"""
return self.dataset.sample(num_samples)
def add_samples(self, samples):
"""生成后调用(默认为空操作)。"""
pass
```
### 带缓冲区的数据源(离线策略)
```python
class RolloutDataSourceWithBuffer(RolloutDataSource):
def __init__(self):
self.buffer = []
def add_samples(self, samples):
"""存储已生成的样本以供复用。"""
self.buffer.extend(samples)
def buffer_filter(self, args, buffer, num_samples):
"""自定义选择逻辑(优先级、分层等)。"""
return select_best(buffer, num_samples)
```
---
## 常见问题与解决方案
### 问题:SGLang 引擎崩溃
**现象**:推理引擎在训练中途退出
**解决方案**
```bash
# 启用容错
--use-fault-tolerance
# 增加内存分配
--sglang-mem-fraction-static 0.85
# 减小批大小
--rollout-batch-size 16
```
### 问题:权重同步超时
**现象**rollout 后训练挂起
**解决方案**
```bash
# 增大同步间隔
--update-weights-interval 5
# 使用 colocate 模式(无网络传输)
--colocate
```
### 问题:训练时 OOM
**现象**:反向传播时 CUDA OOM
**解决方案**
```bash
# 启用梯度检查点
--recompute-activations
# 减小 micro-batch 大小
--micro-batch-size 1
# 启用序列并行
--sequence-parallel
```
### 问题:数据加载缓慢
**现象**:数据获取期间 GPU 空闲
**解决方案**
```bash
# 增加数据 worker 数量
--num-data-workers 4
# 使用流式数据集
--streaming-data
```
---
## 支持的模型
| 模型系列 | 配置 |
|--------------|----------------|
| GLM | GLM-4.5、GLM-4.6、GLM-4.7、GLM-Z1-9B |
| Qwen | Qwen34B、8B、30B-A3B)、Qwen3-MoE、Qwen2.5 |
| DeepSeek | V3、V3.1、R1 |
| Llama | Llama 38B、70B |
| 其他 | Kimi K2、Moonlight-16B |
每个模型在 `scripts/models/` 中均有预配置脚本。
---
## 进阶主题
### Co-location 模式
训练与推理共享 GPU 以减少内存占用:
```bash
python train.py \
--colocate \
--actor-num-gpus-per-node 8 \
--sglang-mem-fraction-static 0.4 \
${MODEL_ARGS[@]}
```
### 自定义奖励模型
```python
# custom_rm.py
class CustomRewardModel:
def __init__(self, model_path):
self.model = load_model(model_path)
def compute_reward(self, prompts, responses):
inputs = self.tokenize(prompts, responses)
scores = self.model(inputs)
return scores.tolist()
```
```bash
--custom-rm-path custom_rm.py
```
### 多任务评估
```bash
--eval-prompt-data aime /path/to/aime.jsonl \
--eval-prompt-data gsm8k /path/to/gsm8k.jsonl \
--n-samples-per-eval-prompt 16
```
---
## 资源
- **文档**https://thudm.github.io/slime/
- **GitHub**https://github.com/THUDM/slime
- **博客**https://lmsys.org/blog/2025-07-09-slime/
- **示例**:参见 `examples/` 目录,包含 14+ 个完整示例
@@ -0,0 +1,542 @@
---
title: "Stable Diffusion 图像生成"
sidebar_label: "Stable Diffusion 图像生成"
description: "通过 HuggingFace Diffusers 使用 Stable Diffusion 模型实现最先进的文本到图像生成"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Stable Diffusion 图像生成
通过 HuggingFace Diffusers 使用 Stable Diffusion 模型实现最先进的文本到图像生成。适用于从文本 prompt(提示词)生成图像、执行图像到图像转换、图像修复(inpainting),或构建自定义扩散 pipeline。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/stable-diffusion` 安装 |
| 路径 | `optional-skills/mlops/stable-diffusion` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `diffusers>=0.30.0`, `transformers>=4.41.0`, `accelerate>=0.31.0`, `torch>=2.0.0` |
| 平台 | linux, macos, windows |
| 标签 | `Image Generation`, `Stable Diffusion`, `Diffusers`, `Text-to-Image`, `Multimodal`, `Computer Vision` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Stable Diffusion 图像生成
使用 HuggingFace Diffusers 库通过 Stable Diffusion 生成图像的综合指南。
## 何时使用 Stable Diffusion
**在以下情况下使用 Stable Diffusion**
- 从文本描述生成图像
- 执行图像到图像转换(风格迁移、增强)
- Inpainting(填充遮罩区域)
- Outpainting(将图像扩展至边界之外)
- 创建现有图像的变体
- 构建自定义图像生成工作流
**核心功能:**
- **文本到图像**:从自然语言 prompt 生成图像
- **图像到图像**:在文本引导下转换现有图像
- **Inpainting**:用上下文感知内容填充遮罩区域
- **ControlNet**:添加空间条件控制(边缘、姿态、深度)
- **LoRA 支持**:高效微调与风格适配
- **多模型支持**:支持 SD 1.5、SDXL、SD 3.0、Flux
**改用以下替代方案:**
- **DALL-E 3**:无需 GPU 的 API 生成
- **Midjourney**:艺术化、风格化输出
- **Imagen**Google Cloud 集成
- **Leonardo.ai**:基于 Web 的创意工作流
## 快速开始
### 安装
```bash
pip install diffusers transformers accelerate torch
pip install xformers # Optional: memory-efficient attention
```
### 基础文本到图像
```python
from diffusers import DiffusionPipeline
import torch
# Load pipeline (auto-detects model type)
pipe = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
torch_dtype=torch.float16
)
pipe.to("cuda")
# Generate image
image = pipe(
"A serene mountain landscape at sunset, highly detailed",
num_inference_steps=50,
guidance_scale=7.5
).images[0]
image.save("output.png")
```
### 使用 SDXL(更高质量)
```python
from diffusers import AutoPipelineForText2Image
import torch
pipe = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16"
)
pipe.to("cuda")
# Enable memory optimization
pipe.enable_model_cpu_offload()
image = pipe(
prompt="A futuristic city with flying cars, cinematic lighting",
height=1024,
width=1024,
num_inference_steps=30
).images[0]
```
## 架构概览
### 三支柱设计
Diffusers 围绕三个核心组件构建:
<!-- ascii-guard-ignore -->
```
Pipeline (orchestration)
├── Model (neural networks)
│ ├── UNet / Transformer (noise prediction)
│ ├── VAE (latent encoding/decoding)
│ └── Text Encoder (CLIP/T5)
└── Scheduler (denoising algorithm)
```
<!-- ascii-guard-ignore-end -->
### Pipeline 推理流程
```
Text Prompt → Text Encoder → Text Embeddings
Random Noise → [Denoising Loop] ← Scheduler
Predicted Noise
VAE Decoder → Final Image
```
## 核心概念
### Pipeline
Pipeline 编排完整工作流:
| Pipeline | 用途 |
|----------|---------|
| `StableDiffusionPipeline` | 文本到图像(SD 1.x/2.x |
| `StableDiffusionXLPipeline` | 文本到图像(SDXL |
| `StableDiffusion3Pipeline` | 文本到图像(SD 3.0 |
| `FluxPipeline` | 文本到图像(Flux 模型) |
| `StableDiffusionImg2ImgPipeline` | 图像到图像 |
| `StableDiffusionInpaintPipeline` | Inpainting |
### Scheduler
Scheduler 控制去噪过程:
| Scheduler | 步数 | 质量 | 适用场景 |
|-----------|-------|---------|----------|
| `EulerDiscreteScheduler` | 20-50 | 良好 | 默认选择 |
| `EulerAncestralDiscreteScheduler` | 20-50 | 良好 | 更多变化 |
| `DPMSolverMultistepScheduler` | 15-25 | 优秀 | 快速、高质量 |
| `DDIMScheduler` | 50-100 | 良好 | 确定性生成 |
| `LCMScheduler` | 4-8 | 良好 | 极速生成 |
| `UniPCMultistepScheduler` | 15-25 | 优秀 | 快速收敛 |
### 切换 Scheduler
```python
from diffusers import DPMSolverMultistepScheduler
# Swap for faster generation
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
pipe.scheduler.config
)
# Now generate with fewer steps
image = pipe(prompt, num_inference_steps=20).images[0]
```
## 生成参数
### 关键参数
| 参数 | 默认值 | 说明 |
|-----------|---------|-------------|
| `prompt` | 必填 | 目标图像的文本描述 |
| `negative_prompt` | None | 图像中需要避免的内容 |
| `num_inference_steps` | 50 | 去噪步数(越多质量越好) |
| `guidance_scale` | 7.5 | Prompt 遵循程度(通常为 7-12 |
| `height`, `width` | 512/1024 | 输出尺寸(8 的倍数) |
| `generator` | None | 用于可复现性的 Torch generator |
| `num_images_per_prompt` | 1 | 批量大小 |
### 可复现生成
```python
import torch
generator = torch.Generator(device="cuda").manual_seed(42)
image = pipe(
prompt="A cat wearing a top hat",
generator=generator,
num_inference_steps=50
).images[0]
```
### Negative prompt
```python
image = pipe(
prompt="Professional photo of a dog in a garden",
negative_prompt="blurry, low quality, distorted, ugly, bad anatomy",
guidance_scale=7.5
).images[0]
```
## 图像到图像
在文本引导下转换现有图像:
```python
from diffusers import AutoPipelineForImage2Image
from PIL import Image
pipe = AutoPipelineForImage2Image.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
torch_dtype=torch.float16
).to("cuda")
init_image = Image.open("input.jpg").resize((512, 512))
image = pipe(
prompt="A watercolor painting of the scene",
image=init_image,
strength=0.75, # How much to transform (0-1)
num_inference_steps=50
).images[0]
```
## Inpainting
填充遮罩区域:
```python
from diffusers import AutoPipelineForInpainting
from PIL import Image
pipe = AutoPipelineForInpainting.from_pretrained(
"runwayml/stable-diffusion-inpainting",
torch_dtype=torch.float16
).to("cuda")
image = Image.open("photo.jpg")
mask = Image.open("mask.png") # White = inpaint region
result = pipe(
prompt="A red car parked on the street",
image=image,
mask_image=mask,
num_inference_steps=50
).images[0]
```
## ControlNet
添加空间条件控制以实现精确控制:
```python
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch
# Load ControlNet for edge conditioning
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/control_v11p_sd15_canny",
torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16
).to("cuda")
# Use Canny edge image as control
control_image = get_canny_image(input_image)
image = pipe(
prompt="A beautiful house in the style of Van Gogh",
image=control_image,
num_inference_steps=30
).images[0]
```
### 可用的 ControlNet
| ControlNet | 输入类型 | 适用场景 |
|------------|------------|----------|
| `canny` | 边缘图 | 保留结构 |
| `openpose` | 姿态骨架 | 人体姿态 |
| `depth` | 深度图 | 3D 感知生成 |
| `normal` | 法线图 | 表面细节 |
| `mlsd` | 线段 | 建筑线条 |
| `scribble` | 粗略草图 | 草图到图像 |
## LoRA 适配器
加载微调风格适配器:
```python
from diffusers import DiffusionPipeline
pipe = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
torch_dtype=torch.float16
).to("cuda")
# Load LoRA weights
pipe.load_lora_weights("path/to/lora", weight_name="style.safetensors")
# Generate with LoRA style
image = pipe("A portrait in the trained style").images[0]
# Adjust LoRA strength
pipe.fuse_lora(lora_scale=0.8)
# Unload LoRA
pipe.unload_lora_weights()
```
### 多个 LoRA
```python
# Load multiple LoRAs
pipe.load_lora_weights("lora1", adapter_name="style")
pipe.load_lora_weights("lora2", adapter_name="character")
# Set weights for each
pipe.set_adapters(["style", "character"], adapter_weights=[0.7, 0.5])
image = pipe("A portrait").images[0]
```
## 内存优化
### 启用 CPU 卸载
```python
# Model CPU offload - moves models to CPU when not in use
pipe.enable_model_cpu_offload()
# Sequential CPU offload - more aggressive, slower
pipe.enable_sequential_cpu_offload()
```
### Attention 切片
```python
# Reduce memory by computing attention in chunks
pipe.enable_attention_slicing()
# Or specific chunk size
pipe.enable_attention_slicing("max")
```
### xFormers 内存高效 Attention
```python
# Requires xformers package
pipe.enable_xformers_memory_efficient_attention()
```
### 大图像的 VAE 切片
```python
# Decode latents in tiles for large images
pipe.enable_vae_slicing()
pipe.enable_vae_tiling()
```
## 模型变体
### 加载不同精度
```python
# FP16 (recommended for GPU)
pipe = DiffusionPipeline.from_pretrained(
"model-id",
torch_dtype=torch.float16,
variant="fp16"
)
# BF16 (better precision, requires Ampere+ GPU)
pipe = DiffusionPipeline.from_pretrained(
"model-id",
torch_dtype=torch.bfloat16
)
```
### 加载特定组件
```python
from diffusers import UNet2DConditionModel, AutoencoderKL
# Load custom VAE
vae = AutoencoderKL.from_pretrained("stabilityai/sd-vae-ft-mse")
# Use with pipeline
pipe = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
vae=vae,
torch_dtype=torch.float16
)
```
## 批量生成
高效生成多张图像:
```python
# Multiple prompts
prompts = [
"A cat playing piano",
"A dog reading a book",
"A bird painting a picture"
]
images = pipe(prompts, num_inference_steps=30).images
# Multiple images per prompt
images = pipe(
"A beautiful sunset",
num_images_per_prompt=4,
num_inference_steps=30
).images
```
## 常见工作流
### 工作流 1:高质量生成
```python
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler
import torch
# 1. Load SDXL with optimizations
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16"
)
pipe.to("cuda")
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_model_cpu_offload()
# 2. Generate with quality settings
image = pipe(
prompt="A majestic lion in the savanna, golden hour lighting, 8k, detailed fur",
negative_prompt="blurry, low quality, cartoon, anime, sketch",
num_inference_steps=30,
guidance_scale=7.5,
height=1024,
width=1024
).images[0]
```
### 工作流 2:快速原型验证
```python
from diffusers import AutoPipelineForText2Image, LCMScheduler
import torch
# Use LCM for 4-8 step generation
pipe = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16
).to("cuda")
# Load LCM LoRA for fast generation
pipe.load_lora_weights("latent-consistency/lcm-lora-sdxl")
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
pipe.fuse_lora()
# Generate in ~1 second
image = pipe(
"A beautiful landscape",
num_inference_steps=4,
guidance_scale=1.0
).images[0]
```
## 常见问题
**CUDA 内存不足:**
```python
# Enable memory optimizations
pipe.enable_model_cpu_offload()
pipe.enable_attention_slicing()
pipe.enable_vae_slicing()
# Or use lower precision
pipe = DiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
```
**黑色/噪声图像:**
```python
# Check VAE configuration
# Use safety checker bypass if needed
pipe.safety_checker = None
# Ensure proper dtype consistency
pipe = pipe.to(dtype=torch.float16)
```
**生成速度慢:**
```python
# Use faster scheduler
from diffusers import DPMSolverMultistepScheduler
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
# Reduce steps
image = pipe(prompt, num_inference_steps=20).images[0]
```
## 参考资料
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/stable-diffusion/references/advanced-usage.md)** - 自定义 pipeline、微调、部署
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/stable-diffusion/references/troubleshooting.md)** - 常见问题与解决方案
## 资源
- **文档**https://huggingface.co/docs/diffusers
- **代码仓库**https://github.com/huggingface/diffusers
- **模型中心**https://huggingface.co/models?library=diffusers
- **Discord**https://discord.gg/diffusers
@@ -0,0 +1,206 @@
---
title: "Tensorrt Llm — 使用 NVIDIA TensorRT 优化 LLM 推理以实现最大吞吐量和最低延迟"
sidebar_label: "Tensorrt Llm"
description: "使用 NVIDIA TensorRT 优化 LLM 推理以实现最大吞吐量和最低延迟"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Tensorrt Llm
使用 NVIDIA TensorRT 优化 LLM 推理,实现最大吞吐量和最低延迟。适用于在 NVIDIA GPU(A100/H100)上进行生产部署、需要比 PyTorch 快 10-100 倍的推理速度,或需要使用量化(FP8/INT4)、in-flight batching(动态批处理)和多 GPU 扩展来服务模型的场景。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/tensorrt-llm` 安装 |
| 路径 | `optional-skills/mlops/tensorrt-llm` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `tensorrt-llm`, `torch` |
| 平台 | linux, macos |
| 标签 | `Inference Serving`, `TensorRT-LLM`, `NVIDIA`, `Inference Optimization`, `High Throughput`, `Low Latency`, `Production`, `FP8`, `INT4`, `In-Flight Batching`, `Multi-GPU` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# TensorRT-LLM
NVIDIA 的开源库,用于在 NVIDIA GPU 上以最先进的性能优化 LLM 推理。
## 何时使用 TensorRT-LLM
**在以下情况下使用 TensorRT-LLM**
- 在 NVIDIA GPUA100、H100、GB200)上部署
- 需要最大吞吐量(Llama 3 上 24,000+ tokens/sec
- 实时应用需要低延迟
- 使用量化模型(FP8、INT4、FP4)
- 跨多个 GPU 或节点扩展
**在以下情况下改用 vLLM**
- 需要更简单的设置和 Python 优先的 API
- 希望使用 PagedAttention 而无需 TensorRT 编译
- 使用 AMD GPU 或非 NVIDIA 硬件
**在以下情况下改用 llama.cpp**
- 在 CPU 或 Apple Silicon 上部署
- 需要无 NVIDIA GPU 的边缘部署
- 希望使用更简单的 GGUF 量化格式
## 快速开始
### 安装
```bash
# Docker(推荐)
docker pull nvidia/tensorrt_llm:latest
# pip 安装
pip install tensorrt_llm==1.2.0rc3
# 需要 CUDA 13.0.0、TensorRT 10.13.2、Python 3.10-3.12
```
### 基本推理
```python
from tensorrt_llm import LLM, SamplingParams
# 初始化模型
llm = LLM(model="meta-llama/Meta-Llama-3-8B")
# 配置采样参数
sampling_params = SamplingParams(
max_tokens=100,
temperature=0.7,
top_p=0.9
)
# 生成
prompts = ["Explain quantum computing"]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
print(output.text)
```
### 使用 trtllm-serve 提供服务
```bash
# 启动服务器(自动下载和编译模型)
trtllm-serve meta-llama/Meta-Llama-3-8B \
--tp_size 4 \ # 张量并行(4 个 GPU)
--max_batch_size 256 \
--max_num_tokens 4096
# 客户端请求
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Meta-Llama-3-8B",
"messages": [{"role": "user", "content": "Hello!"}],
"temperature": 0.7,
"max_tokens": 100
}'
```
## 核心特性
### 性能优化
- **In-flight batching**:生成过程中的动态批处理
- **Paged KV cache**:高效内存管理
- **Flash Attention**:优化的注意力计算核
- **量化**:FP8、INT4、FP4,推理速度提升 2-4 倍
- **CUDA graphs**:降低内核启动开销
### 并行化
- **张量并行(TP**:跨 GPU 拆分模型
- **流水线并行(PP**:按层分布
- **专家并行**:用于混合专家(Mixture-of-Experts)模型
- **多节点**:扩展至单机以外
### 高级特性
- **推测解码(Speculative decoding**:使用草稿模型加速生成
- **LoRA serving**:高效多适配器部署
- **分离式服务(Disaggregated serving**:预填充与生成分离
## 常见模式
### 量化模型(FP8
```python
from tensorrt_llm import LLM
# 加载 FP8 量化模型(速度提升 2 倍,内存减少 50%)
llm = LLM(
model="meta-llama/Meta-Llama-3-70B",
dtype="fp8",
max_num_tokens=8192
)
# 推理方式与之前相同
outputs = llm.generate(["Summarize this article..."])
```
### 多 GPU 部署
```python
# 跨 8 个 GPU 的张量并行
llm = LLM(
model="meta-llama/Meta-Llama-3-405B",
tensor_parallel_size=8,
dtype="fp8"
)
```
### 批量推理
```python
# 高效处理 100 个 prompt
prompts = [f"Question {i}: ..." for i in range(100)]
outputs = llm.generate(
prompts,
sampling_params=SamplingParams(max_tokens=200)
)
# 自动 in-flight batching 以实现最大吞吐量
```
## 性能基准
**Meta Llama 3-8B**H100 GPU):
- 吞吐量:24,000 tokens/sec
- 延迟:每 token 约 10ms
- 对比 PyTorch**快 100 倍**
**Llama 3-70B**8× A100 80GB):
- FP8 量化:比 FP16 快 2 倍
- 内存:FP8 减少 50%
## 支持的模型
- **LLaMA 系列**Llama 2、Llama 3、CodeLlama
- **GPT 系列**GPT-2、GPT-J、GPT-NeoX
- **Qwen**Qwen、Qwen2、QwQ
- **DeepSeek**DeepSeek-V2、DeepSeek-V3
- **Mixtral**Mixtral-8x7B、Mixtral-8x22B
- **视觉模型**LLaVA、Phi-3-vision
- **100+ 模型**,可在 HuggingFace 上获取
## 参考文档
- **[优化指南](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/tensorrt-llm/references/optimization.md)** — 量化、批处理、KV cache 调优
- **[多 GPU 配置](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/tensorrt-llm/references/multi-gpu.md)** — 张量/流水线并行、多节点
- **[服务指南](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/tensorrt-llm/references/serving.md)** — 生产部署、监控、自动扩缩容
## 资源
- **文档**https://nvidia.github.io/TensorRT-LLM/
- **GitHub**https://github.com/NVIDIA/TensorRT-LLM
- **模型**https://huggingface.co/models?library=tensorrt_llm
@@ -0,0 +1,378 @@
---
title: "Distributed Llm Pretraining Torchtitan"
sidebar_label: "Distributed Llm Pretraining Torchtitan"
description: "使用 torchtitan 提供 PyTorch 原生分布式 LLM 预训练,支持 4D 并行(FSDP2、TP、PP、CP"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Distributed Llm Pretraining Torchtitan
使用 torchtitan 提供 PyTorch 原生分布式 LLM 预训练,支持 4D 并行(FSDP2、TP、PP、CP)。适用于在 8 到 512+ GPU 规模下预训练 Llama 3.1、DeepSeek V3 或自定义模型,支持 Float8、torch.compile 及分布式检查点。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/torchtitan` 安装 |
| 路径 | `optional-skills/mlops/torchtitan` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖 | `torch>=2.6.0`, `torchtitan>=0.2.0`, `torchao>=0.5.0` |
| 平台 | linux, macos |
| 标签 | `Model Architecture`, `Distributed Training`, `TorchTitan`, `FSDP2`, `Tensor Parallel`, `Pipeline Parallel`, `Context Parallel`, `Float8`, `Llama`, `Pretraining` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# TorchTitan - PyTorch 原生分布式 LLM 预训练
## 快速开始
TorchTitan 是 PyTorch 官方的大规模 LLM 预训练平台,支持可组合的 4D 并行(FSDP2、TP、PP、CP),在 H100 GPU 上相比基线可实现 65%+ 的加速。
**安装**
```bash
# 从 PyPI 安装(稳定版)
pip install torchtitan
# 从源码安装(最新特性,需要 PyTorch nightly
git clone https://github.com/pytorch/torchtitan
cd torchtitan
pip install -r requirements.txt
```
**下载 tokenizer**
```bash
# 从 https://huggingface.co/settings/tokens 获取 HF token
python scripts/download_hf_assets.py --repo_id meta-llama/Llama-3.1-8B --assets tokenizer --hf_token=...
```
**在 8 个 GPU 上启动训练**:
```bash
CONFIG_FILE="./torchtitan/models/llama3/train_configs/llama3_8b.toml" ./run_train.sh
```
## 常用工作流
### 工作流 1:在单节点上预训练 Llama 3.1 8B
复制此检查清单:
```
单节点预训练:
- [ ] 步骤 1:下载 tokenizer
- [ ] 步骤 2:配置训练
- [ ] 步骤 3:启动训练
- [ ] 步骤 4:监控与检查点
```
**步骤 1:下载 tokenizer**
```bash
python scripts/download_hf_assets.py \
--repo_id meta-llama/Llama-3.1-8B \
--assets tokenizer \
--hf_token=YOUR_HF_TOKEN
```
**步骤 2:配置训练**
编辑或创建 TOML 配置文件:
```toml
# llama3_8b_custom.toml
[job]
dump_folder = "./outputs"
description = "Llama 3.1 8B training"
[model]
name = "llama3"
flavor = "8B"
hf_assets_path = "./assets/hf/Llama-3.1-8B"
[optimizer]
name = "AdamW"
lr = 3e-4
[lr_scheduler]
warmup_steps = 200
[training]
local_batch_size = 2
seq_len = 8192
max_norm = 1.0
steps = 1000
dataset = "c4"
[parallelism]
data_parallel_shard_degree = -1 # Use all GPUs for FSDP
[activation_checkpoint]
mode = "selective"
selective_ac_option = "op"
[checkpoint]
enable = true
folder = "checkpoint"
interval = 500
```
**步骤 3:启动训练**
```bash
# 单节点 8 个 GPU
CONFIG_FILE="./llama3_8b_custom.toml" ./run_train.sh
# 或显式使用 torchrun
torchrun --nproc_per_node=8 \
-m torchtitan.train \
--job.config_file ./llama3_8b_custom.toml
```
**步骤 4:监控与检查点**
TensorBoard 日志保存至 `./outputs/tb/`
```bash
tensorboard --logdir ./outputs/tb
```
### 工作流 2:使用 SLURM 进行多节点训练
```
多节点训练:
- [ ] 步骤 1:为规模配置并行度
- [ ] 步骤 2:设置 SLURM 脚本
- [ ] 步骤 3:提交作业
- [ ] 步骤 4:从检查点恢复
```
**步骤 1:为规模配置并行度**
在 256 个 GPU(32 个节点)上训练 70B 模型:
```toml
[parallelism]
data_parallel_shard_degree = 32 # FSDP across 32 ranks
tensor_parallel_degree = 8 # TP within node
pipeline_parallel_degree = 1 # No PP for 70B
context_parallel_degree = 1 # Increase for long sequences
```
**步骤 2:设置 SLURM 脚本**
```bash
#!/bin/bash
#SBATCH --job-name=llama70b
#SBATCH --nodes=32
#SBATCH --ntasks-per-node=8
#SBATCH --gpus-per-node=8
srun torchrun \
--nnodes=32 \
--nproc_per_node=8 \
--rdzv_backend=c10d \
--rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT \
-m torchtitan.train \
--job.config_file ./llama3_70b.toml
```
**步骤 3:提交作业**
```bash
sbatch multinode_trainer.slurm
```
**步骤 4:从检查点恢复**
若配置的文件夹中存在检查点,训练将自动恢复。
### 工作流 3:为 H100 启用 Float8 训练
Float8 在 H100 GPU 上可提供 30-50% 的加速。
```
Float8 训练:
- [ ] 步骤 1:安装 torchao
- [ ] 步骤 2:配置 Float8
- [ ] 步骤 3:启动并开启 compile
```
**步骤 1:安装 torchao**
```bash
USE_CPP=0 pip install git+https://github.com/pytorch/ao.git
```
**步骤 2:配置 Float8**
在 TOML 配置中添加:
```toml
[model]
converters = ["quantize.linear.float8"]
[quantize.linear.float8]
enable_fsdp_float8_all_gather = true
precompute_float8_dynamic_scale_for_fsdp = true
filter_fqns = ["output"] # Exclude output layer
[compile]
enable = true
components = ["model", "loss"]
```
**步骤 3:启动并开启 compile**
```bash
CONFIG_FILE="./llama3_8b.toml" ./run_train.sh \
--model.converters="quantize.linear.float8" \
--quantize.linear.float8.enable_fsdp_float8_all_gather \
--compile.enable
```
### 工作流 4405B 模型的 4D 并行
```
4D 并行(FSDP + TP + PP + CP):
- [ ] 步骤 1:创建种子检查点
- [ ] 步骤 2:配置 4D 并行
- [ ] 步骤 3:在 512 个 GPU 上启动
```
**步骤 1:创建种子检查点**
跨 PP 阶段一致初始化所必需:
```bash
NGPU=1 CONFIG_FILE=./llama3_405b.toml ./run_train.sh \
--checkpoint.enable \
--checkpoint.create_seed_checkpoint \
--parallelism.data_parallel_shard_degree 1 \
--parallelism.tensor_parallel_degree 1 \
--parallelism.pipeline_parallel_degree 1
```
**步骤 2:配置 4D 并行**
```toml
[parallelism]
data_parallel_shard_degree = 8 # FSDP
tensor_parallel_degree = 8 # TP within node
pipeline_parallel_degree = 8 # PP across nodes
context_parallel_degree = 1 # CP for long sequences
[training]
local_batch_size = 32
seq_len = 8192
```
**步骤 3:在 512 个 GPU 上启动**
```bash
# 64 节点 x 8 GPU = 512 GPU
srun torchrun --nnodes=64 --nproc_per_node=8 \
-m torchtitan.train \
--job.config_file ./llama3_405b.toml
```
## 何时使用 vs 替代方案
**使用 TorchTitan 的场景:**
- 从头预训练 LLM8B 到 405B+
- 需要无第三方依赖的 PyTorch 原生方案
- 需要可组合的 4D 并行(FSDP2、TP、PP、CP
- 在支持 Float8 的 H100 上训练
- 需要与 torchtune/HuggingFace 互操作的检查点
**使用替代方案的场景:**
- **Megatron-LM**:仅限 NVIDIA 部署时追求最高性能
- **DeepSpeed**:更广泛的 ZeRO 优化生态,支持推理
- **Axolotl/TRL**:微调而非预训练
- **LitGPT**:教学用途,小规模训练
## 常见问题
**问题:大模型内存不足**
启用激活检查点并减小批次大小:
```toml
[activation_checkpoint]
mode = "full" # Instead of "selective"
[training]
local_batch_size = 1
```
或使用梯度累积:
```toml
[training]
local_batch_size = 1
global_batch_size = 32 # Accumulates gradients
```
**问题:TP 异步集合通信导致内存占用过高**
设置环境变量:
```bash
export TORCH_NCCL_AVOID_RECORD_STREAMS=1
```
**问题:Float8 训练未见加速**
Float8 仅对大型 GEMM 有效。过滤小层:
```toml
[quantize.linear.float8]
filter_fqns = ["attention.wk", "attention.wv", "output", "auto_filter_small_kn"]
```
**问题:更改并行度后检查点加载失败**
使用 DCP 的重分片功能:
```bash
# 将分片检查点转换为单文件
python -m torch.distributed.checkpoint.format_utils \
dcp_to_torch checkpoint/step-1000 checkpoint.pt
```
**问题:Pipeline 并行初始化失败**
请先创建种子检查点(参见工作流 4,步骤 1)。
## 支持的模型
| 模型 | 规模 | 状态 |
|-------|-------|--------|
| Llama 3.1 | 8B, 70B, 405B | 生产可用 |
| Llama 4 | 多种 | 实验性 |
| DeepSeek V3 | 16B, 236B, 671B (MoE) | 实验性 |
| GPT-OSS | 20B, 120B (MoE) | 实验性 |
| Qwen 3 | 多种 | 实验性 |
| Flux | 扩散模型 | 实验性 |
## 性能基准(H100
| 模型 | GPU 数 | 并行策略 | TPS/GPU | 技术 |
|-------|------|-------------|---------|------------|
| Llama 8B | 8 | FSDP | 5,762 | 基线 |
| Llama 8B | 8 | FSDP+compile+FP8 | 8,532 | +48% |
| Llama 70B | 256 | FSDP+TP+AsyncTP | 876 | 2D 并行 |
| Llama 405B | 512 | FSDP+TP+PP | 128 | 3D 并行 |
## 进阶主题
**FSDP2 配置**:参见 [references/fsdp.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/torchtitan/references/fsdp.md),了解 FSDP2 与 FSDP1 的详细对比及 ZeRO 等价关系。
**Float8 训练**:参见 [references/float8.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/torchtitan/references/float8.md),了解 tensorwise 与 rowwise 缩放方案。
**检查点**:参见 [references/checkpoint.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/torchtitan/references/checkpoint.md),了解 HuggingFace 转换与异步检查点。
**添加自定义模型**:参见 [references/custom-models.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/torchtitan/references/custom-models.md),了解 TrainSpec 协议。
## 资源
- GitHubhttps://github.com/pytorch/torchtitan
- 论文:https://arxiv.org/abs/2410.06511
- ICLR 2025https://iclr.cc/virtual/2025/poster/29620
- PyTorch 论坛:https://discuss.pytorch.org/c/distributed/torchtitan/44
@@ -0,0 +1,181 @@
---
title: "Axolotl — Axolotl:基于 YAML 的 LLM 微调(LoRA、DPO、GRPO"
sidebar_label: "Axolotl"
description: "Axolotl:基于 YAML 的 LLM 微调(LoRA、DPO、GRPO"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Axolotl
Axolotl:基于 YAML 的 LLM 微调(LoRA、DPO、GRPO)。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/axolotl` 安装 |
| 路径 | `optional-skills/mlops/training/axolotl` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `axolotl`, `torch`, `transformers`, `datasets`, `peft`, `accelerate`, `deepspeed` |
| 平台 | linux, macos |
| 标签 | `Fine-Tuning`, `Axolotl`, `LLM`, `LoRA`, `QLoRA`, `DPO`, `KTO`, `ORPO`, `GRPO`, `YAML`, `HuggingFace`, `DeepSpeed`, `Multimodal` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Axolotl Skill
## 内容概览
使用 Axolotl 微调 LLM 的专家指导 — YAML 配置、100+ 模型、LoRA/QLoRA、DPO/KTO/ORPO/GRPO、多模态支持。
基于官方文档生成的 axolotl 开发全面辅助。
## 何时使用此 Skill
以下情况应触发此 skill
- 使用 axolotl 进行开发
- 询问 axolotl 功能或 API
- 实现 axolotl 解决方案
- 调试 axolotl 代码
- 学习 axolotl 最佳实践
## 快速参考
### 常用模式
**模式 1:** 若要验证训练任务是否具备可接受的数据传输速度,运行 NCCL Tests 有助于定位瓶颈,例如:
```
./build/all_reduce_perf -b 8 -e 128M -f 2 -g 3
```
**模式 2** 在 Axolotl yaml 中配置模型以使用 FSDP,例如:
```
fsdp_version: 2
fsdp_config:
offload_params: true
state_dict_type: FULL_STATE_DICT
auto_wrap_policy: TRANSFORMER_BASED_WRAP
transformer_layer_cls_to_wrap: LlamaDecoderLayer
reshard_after_forward: true
```
**模式 3** `context_parallel_size` 应为 GPU 总数的因数,例如:
```
context_parallel_size
```
**模式 4** 例如:- 使用 8 块 GPU 且不启用序列并行时:每步处理 8 个不同批次 - 使用 8 块 GPU 且 `context_parallel_size=4` 时:每步仅处理 2 个不同批次(每个批次跨 4 块 GPU 拆分)- 若每块 GPU 的 `micro_batch_size` 为 2,全局批次大小将从 16 降至 4
```
context_parallel_size=4
```
**模式 5** 在配置中设置 `save_compressed: true` 可启用压缩格式保存模型,效果如下:- 磁盘空间占用减少约 40% - 保持与 vLLM 的兼容性以加速推理 - 保持与 llmcompressor 的兼容性以进行进一步优化(例如:量化)
```
save_compressed: true
```
**模式 6:** 注意:无需将集成放置在 `integrations` 文件夹中。只要安装在 Python 环境的某个包中,可位于任意位置。参见此示例仓库:https://github.com/axolotl-ai-cloud/diff-transformer
```
integrations
```
**模式 7:** 同时处理单样本和批量数据。- 单样本:`sample['input_ids']``list[int]` - 批量数据:`sample['input_ids']``list[list[int]]`
```
utils.trainer.drop_long_seq(sample, sequence_len=2048, min_sequence_len=2)
```
### 代码示例模式
**示例 1**python):
```python
cli.cloud.modal_.ModalCloud(config, app=None)
```
**示例 2**python):
```python
cli.cloud.modal_.run_cmd(cmd, run_folder, volumes=None)
```
**示例 3**python):
```python
core.trainers.base.AxolotlTrainer(
*_args,
bench_data_collator=None,
eval_data_collator=None,
dataset_tags=None,
**kwargs,
)
```
**示例 4**python):
```python
core.trainers.base.AxolotlTrainer.log(logs, start_time=None)
```
**示例 5**python):
```python
prompt_strategies.input_output.RawInputOutputPrompter()
```
## 参考文件
此 skill 在 `references/` 中包含完整文档:
- **api.md** - API 文档
- **dataset-formats.md** - Dataset-Formats 文档
- **other.md** - 其他文档
需要详细信息时,使用 `view` 读取特定参考文件。
## 使用此 Skill
### 初学者
`getting_started``tutorials` 参考文件入手,了解基础概念。
### 特定功能
使用对应分类的参考文件(api、guides 等)获取详细信息。
### 代码示例
上方快速参考部分包含从官方文档中提取的常用模式。
## 资源
### references/
从官方来源提取的有组织文档,包含:
- 详细说明
- 带语言标注的代码示例
- 原始文档链接
- 便于快速导航的目录
### scripts/
在此添加常见自动化任务的辅助脚本。
### assets/
在此添加模板、样板代码或示例项目。
## 说明
- 此 skill 由官方文档自动生成
- 参考文件保留了源文档的结构与示例
- 代码示例包含语言检测以提供更好的语法高亮
- 快速参考模式从文档中的常见用法示例中提取
## 更新
若要使用最新文档刷新此 skill
1. 使用相同配置重新运行爬取程序
2. Skill 将以最新信息重新构建
@@ -0,0 +1,477 @@
---
title: "使用 TRL 进行微调 — TRL:面向 LLM RLHF 的 SFT、DPO、PPO、GRPO 及奖励建模"
sidebar_label: "使用 TRL 进行微调"
description: "TRL:面向 LLM RLHF 的 SFT、DPO、PPO、GRPO 及奖励建模"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# 使用 TRL 进行微调
TRL:面向 LLM RLHF 的 SFT、DPO、PPO、GRPO 及奖励建模。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/trl-fine-tuning` 安装 |
| 路径 | `optional-skills/mlops/training/trl-fine-tuning` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `trl`, `transformers`, `datasets`, `peft`, `accelerate`, `torch` |
| 平台 | linux, macos, windows |
| 标签 | `Post-Training`, `TRL`, `Reinforcement Learning`, `Fine-Tuning`, `SFT`, `DPO`, `PPO`, `GRPO`, `RLHF`, `Preference Alignment`, `HuggingFace` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# TRL - Transformer Reinforcement Learning
## 快速开始
TRL 提供用于将语言模型与人类偏好对齐的后训练(post-training)方法。
**安装**
```bash
pip install trl transformers datasets peft accelerate
```
**监督微调(SFT)**(指令微调):
```python
from trl import SFTTrainer
trainer = SFTTrainer(
model="Qwen/Qwen2.5-0.5B",
train_dataset=dataset, # Prompt-completion pairs
)
trainer.train()
```
**DPO**(偏好对齐):
```python
from trl import DPOTrainer, DPOConfig
config = DPOConfig(output_dir="model-dpo", beta=0.1)
trainer = DPOTrainer(
model=model,
args=config,
train_dataset=preference_dataset, # chosen/rejected pairs
processing_class=tokenizer
)
trainer.train()
```
## 常见工作流
### 工作流 1:完整 RLHF 流水线(SFT → 奖励模型 → PPO)
从基础模型到人类对齐模型的完整流水线。
复制此检查清单:
```
RLHF Training:
- [ ] Step 1: Supervised fine-tuning (SFT)
- [ ] Step 2: Train reward model
- [ ] Step 3: PPO reinforcement learning
- [ ] Step 4: Evaluate aligned model
```
**第 1 步:监督微调**
在指令跟随数据上训练基础模型:
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTTrainer, SFTConfig
from datasets import load_dataset
# Load model
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B")
# Load instruction dataset
dataset = load_dataset("trl-lib/Capybara", split="train")
# Configure training
training_args = SFTConfig(
output_dir="Qwen2.5-0.5B-SFT",
per_device_train_batch_size=4,
num_train_epochs=1,
learning_rate=2e-5,
logging_steps=10,
save_strategy="epoch"
)
# Train
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
tokenizer=tokenizer
)
trainer.train()
trainer.save_model()
```
**第 2 步:训练奖励模型**
训练模型以预测人类偏好:
```python
from transformers import AutoModelForSequenceClassification
from trl import RewardTrainer, RewardConfig
# Load SFT model as base
model = AutoModelForSequenceClassification.from_pretrained(
"Qwen2.5-0.5B-SFT",
num_labels=1 # Single reward score
)
tokenizer = AutoTokenizer.from_pretrained("Qwen2.5-0.5B-SFT")
# Load preference data (chosen/rejected pairs)
dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train")
# Configure training
training_args = RewardConfig(
output_dir="Qwen2.5-0.5B-Reward",
per_device_train_batch_size=2,
num_train_epochs=1,
learning_rate=1e-5
)
# Train reward model
trainer = RewardTrainer(
model=model,
args=training_args,
processing_class=tokenizer,
train_dataset=dataset
)
trainer.train()
trainer.save_model()
```
**第 3 步:PPO 强化学习**
使用奖励模型优化策略:
```bash
python -m trl.scripts.ppo \
--model_name_or_path Qwen2.5-0.5B-SFT \
--reward_model_path Qwen2.5-0.5B-Reward \
--dataset_name trl-internal-testing/descriptiveness-sentiment-trl-style \
--output_dir Qwen2.5-0.5B-PPO \
--learning_rate 3e-6 \
--per_device_train_batch_size 64 \
--total_episodes 10000
```
**第 4 步:评估**
```python
from transformers import pipeline
# Load aligned model
generator = pipeline("text-generation", model="Qwen2.5-0.5B-PPO")
# Test
prompt = "Explain quantum computing to a 10-year-old"
output = generator(prompt, max_length=200)[0]["generated_text"]
print(output)
```
### 工作流 2:使用 DPO 进行简单偏好对齐
无需奖励模型即可对齐模型偏好。
复制此检查清单:
```
DPO Training:
- [ ] Step 1: Prepare preference dataset
- [ ] Step 2: Configure DPO
- [ ] Step 3: Train with DPOTrainer
- [ ] Step 4: Evaluate alignment
```
**第 1 步:准备偏好数据集**
数据集格式:
```json
{
"prompt": "What is the capital of France?",
"chosen": "The capital of France is Paris.",
"rejected": "I don't know."
}
```
加载数据集:
```python
from datasets import load_dataset
dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train")
# Or load your own
# dataset = load_dataset("json", data_files="preferences.json")
```
**第 2 步:配置 DPO**
```python
from trl import DPOConfig
config = DPOConfig(
output_dir="Qwen2.5-0.5B-DPO",
per_device_train_batch_size=4,
num_train_epochs=1,
learning_rate=5e-7,
beta=0.1, # KL penalty strength
max_prompt_length=512,
max_length=1024,
logging_steps=10
)
```
**第 3 步:使用 DPOTrainer 训练**
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
trainer = DPOTrainer(
model=model,
args=config,
train_dataset=dataset,
processing_class=tokenizer
)
trainer.train()
trainer.save_model()
```
**CLI 替代方式**
```bash
trl dpo \
--model_name_or_path Qwen/Qwen2.5-0.5B-Instruct \
--dataset_name argilla/Capybara-Preferences \
--output_dir Qwen2.5-0.5B-DPO \
--per_device_train_batch_size 4 \
--learning_rate 5e-7 \
--beta 0.1
```
### 工作流 3:使用 GRPO 进行内存高效的在线 RL
以最小内存占用进行强化学习训练。
关于深入的 GRPO 指导——奖励函数设计、关键训练洞察(损失行为、模式崩溃、调参)以及高级多阶段模式——请参阅 **[references/grpo-training.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/grpo-training.md)**。生产就绪的训练脚本位于 **[templates/basic_grpo_training.py](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/templates/basic_grpo_training.py)**。
复制此检查清单:
```
GRPO Training:
- [ ] Step 1: Define reward function
- [ ] Step 2: Configure GRPO
- [ ] Step 3: Train with GRPOTrainer
```
**第 1 步:定义奖励函数**
```python
def reward_function(completions, **kwargs):
"""
Compute rewards for completions.
Args:
completions: List of generated texts
Returns:
List of reward scores (floats)
"""
rewards = []
for completion in completions:
# Example: reward based on length and unique words
score = len(completion.split()) # Favor longer responses
score += len(set(completion.lower().split())) # Reward unique words
rewards.append(score)
return rewards
```
或使用奖励模型:
```python
from transformers import pipeline
reward_model = pipeline("text-classification", model="reward-model-path")
def reward_from_model(completions, prompts, **kwargs):
# Combine prompt + completion
full_texts = [p + c for p, c in zip(prompts, completions)]
# Get reward scores
results = reward_model(full_texts)
return [r["score"] for r in results]
```
**第 2 步:配置 GRPO**
```python
from trl import GRPOConfig
config = GRPOConfig(
output_dir="Qwen2-GRPO",
per_device_train_batch_size=4,
num_train_epochs=1,
learning_rate=1e-5,
num_generations=4, # Generate 4 completions per prompt
max_new_tokens=128
)
```
**第 3 步:使用 GRPOTrainer 训练**
```python
from datasets import load_dataset
from trl import GRPOTrainer
# Load prompt-only dataset
dataset = load_dataset("trl-lib/tldr", split="train")
trainer = GRPOTrainer(
model="Qwen/Qwen2-0.5B-Instruct",
reward_funcs=reward_function, # Your reward function
args=config,
train_dataset=dataset
)
trainer.train()
```
**CLI**
```bash
trl grpo \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/tldr \
--output_dir Qwen2-GRPO \
--num_generations 4
```
## 何时使用 TRL 及替代方案
**适合使用 TRL 的场景:**
- 需要将模型与人类偏好对齐
- 拥有偏好数据(chosen/rejected 对)
- 希望使用强化学习(PPO、GRPO)
- 需要训练奖励模型
- 执行完整 RLHF 流水线
**方法选择**
- **SFT**:拥有 prompt-completion 对,需要基础指令跟随
- **DPO**:拥有偏好数据,需要简单对齐(无需奖励模型)
- **PPO**:拥有奖励模型,需要对 RL 进行最大程度的控制
- **GRPO**:内存受限,需要在线 RL
- **奖励模型**:构建 RLHF 流水线,需要对生成内容评分
**改用替代方案的场景:**
- **HuggingFace Trainer**:无需 RL 的基础微调
- **Axolotl**:基于 YAML 的训练配置
- **LitGPT**:教学用途、极简微调
- **Unsloth**:快速 LoRA 训练
## 常见问题
**问题:DPO 训练时显存溢出(OOM)**
减小批次大小和序列长度:
```python
config = DPOConfig(
per_device_train_batch_size=1, # Reduce from 4
max_length=512, # Reduce from 1024
gradient_accumulation_steps=8 # Maintain effective batch
)
```
或启用梯度检查点:
```python
model.gradient_checkpointing_enable()
```
**问题:对齐质量差**
调整 beta 参数:
```python
# Higher beta = more conservative (stays closer to reference)
config = DPOConfig(beta=0.5) # Default 0.1
# Lower beta = more aggressive alignment
config = DPOConfig(beta=0.01)
```
**问题:奖励模型无法学习**
检查损失类型和学习率:
```python
config = RewardConfig(
learning_rate=1e-5, # Try different LR
num_train_epochs=3 # Train longer
)
```
确保偏好数据集有明确的优劣区分:
```python
# Verify dataset
print(dataset[0])
# Should have clear chosen > rejected
```
**问题:PPO 训练不稳定**
调整 KL 系数:
```python
config = PPOConfig(
kl_coef=0.1, # Increase from 0.05
cliprange=0.1 # Reduce from 0.2
)
```
## 高级主题
**SFT 训练指南**:参阅 [references/sft-training.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/sft-training.md),了解数据集格式、chat template、packing 策略及多 GPU 训练。
**DPO 变体**:参阅 [references/dpo-variants.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/dpo-variants.md),了解 IPO、cDPO、RPO 及其他 DPO 损失函数与推荐超参数。
**奖励建模**:参阅 [references/reward-modeling.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/reward-modeling.md),了解结果奖励与过程奖励、Bradley-Terry 损失及奖励模型评估。
**在线 RL 方法**:参阅 [references/online-rl.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/online-rl.md),了解 PPO、GRPO、RLOO 及 OnlineDPO 的详细配置。
**GRPO 深度解析**:参阅 [references/grpo-training.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/references/grpo-training.md),获取专家级 GRPO 模式——奖励函数设计理念、训练洞察(为何损失上升、模式崩溃检测)、超参数调优、多阶段训练及故障排查。生产就绪模板位于 [templates/basic_grpo_training.py](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/mlops/training/trl-fine-tuning/templates/basic_grpo_training.py)。
## 硬件要求
- **GPU**NVIDIA(需要 CUDA
- **显存(VRAM**:取决于模型和方法
- SFT 7B16GB(使用 LoRA
- DPO 7B24GB(存储参考模型)
- PPO 7B:40GB(策略模型 + 奖励模型)
- GRPO 7B24GB(内存效率更高)
- **多 GPU**:通过 `accelerate` 支持
- **混合精度**:推荐 BF16A100/H100
**内存优化**
- 所有方法均可使用 LoRA/QLoRA
- 启用梯度检查点
- 使用更小的批次大小配合梯度累积
## 资源
- 文档:https://huggingface.co/docs/trl/
- GitHubhttps://github.com/huggingface/trl
- 论文:
- "Training language models to follow instructions with human feedback"InstructGPT2022
- "Direct Preference Optimization: Your Language Model is Secretly a Reward Model"DPO2023
- "Group Relative Policy Optimization"GRPO2024
- 示例:https://github.com/huggingface/trl/tree/main/examples/scripts
@@ -0,0 +1,98 @@
---
title: "Unsloth — Unsloth2-5倍更快的 LoRA/QLoRA 微调,更少显存"
sidebar_label: "Unsloth"
description: "Unsloth2-5倍更快的 LoRA/QLoRA 微调,更少显存"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Unsloth
Unsloth2-5倍更快的 LoRA/QLoRA 微调,更少显存。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/unsloth` 安装 |
| 路径 | `optional-skills/mlops/training/unsloth` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `unsloth`, `torch`, `transformers`, `trl`, `datasets`, `peft` |
| 平台 | linux, macos |
| 标签 | `Fine-Tuning`, `Unsloth`, `Fast Training`, `LoRA`, `QLoRA`, `Memory-Efficient`, `Optimization`, `Llama`, `Mistral`, `Gemma`, `Qwen` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# Unsloth Skill
基于官方文档生成的 unsloth 开发综合辅助。
## 何时使用此 Skill
以下情况应触发此 skill
- 使用 unsloth 进行开发
- 询问 unsloth 功能或 API
- 实现 unsloth 解决方案
- 调试 unsloth 代码
- 学习 unsloth 最佳实践
## 快速参考
### 常用模式
*随着你使用此 skill,快速参考模式将逐步添加。*
## 参考文件
此 skill 在 `references/` 中包含完整文档:
- **llms-txt.md** - Llms-Txt 文档
需要详细信息时,使用 `view` 读取特定参考文件。
## 使用此 Skill
### 面向初学者
从 getting_started 或 tutorials 参考文件入手,了解基础概念。
### 针对特定功能
使用相应分类的参考文件(api、guides 等)获取详细信息。
### 获取代码示例
上方快速参考部分包含从官方文档中提取的常用模式。
## 资源
### references/
从官方来源提取的有组织文档,包含:
- 详细说明
- 带语言标注的代码示例
- 原始文档链接
- 便于快速导航的目录
### scripts/
在此添加用于常见自动化任务的辅助脚本。
### assets/
在此添加模板、样板代码或示例项目。
## 说明
- 此 skill 由官方文档自动生成
- 参考文件保留了源文档的结构和示例
- 代码示例包含语言检测以提供更好的语法高亮
- 快速参考模式从文档中的常见用法示例中提取
## 更新
如需使用最新文档刷新此 skill
1. 使用相同配置重新运行爬取程序
2. Skill 将以最新信息重新构建
<!-- Trigger re-upload 1763621536 -->
@@ -0,0 +1,336 @@
---
title: "Whisper — OpenAI 的通用语音识别模型"
sidebar_label: "Whisper"
description: "OpenAI 的通用语音识别模型"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Whisper
OpenAI 的通用语音识别模型。支持 99 种语言、转录、翻译为英语及语言识别。提供六种模型规格,从 tiny(3900 万参数)到 large(15.5 亿参数)。适用于语音转文字、播客转录或多语言音频处理。是鲁棒多语言 ASR(自动语音识别)的首选。
## Skill 元数据
| | |
|---|---|
| 来源 | 可选 — 通过 `hermes skills install official/mlops/whisper` 安装 |
| 路径 | `optional-skills/mlops/whisper` |
| 版本 | `1.0.0` |
| 作者 | Orchestra Research |
| 许可证 | MIT |
| 依赖项 | `openai-whisper`, `transformers`, `torch` |
| 平台 | linux, macos |
| 标签 | `Whisper`, `Speech Recognition`, `ASR`, `Multimodal`, `Multilingual`, `OpenAI`, `Speech-To-Text`, `Transcription`, `Translation`, `Audio Processing` |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# Whisper - 鲁棒语音识别
OpenAI 的多语言语音识别模型。
## 何时使用 Whisper
**适用场景:**
- 语音转文字转录(99 种语言)
- 播客/视频转录
- 会议记录自动化
- 翻译为英语
- 嘈杂音频转录
- 多语言音频处理
**指标**
- **GitHub 72,900+ 星**
- 支持 99 种语言
- 基于 68 万小时音频训练
- MIT 许可证
**改用其他替代方案的情况**
- **AssemblyAI**:托管 API,支持说话人分离
- **Deepgram**:实时流式 ASR
- **Google Speech-to-Text**:基于云端
## 快速开始
### 安装
```bash
# Requires Python 3.8-3.11
pip install -U openai-whisper
# Requires ffmpeg
# macOS: brew install ffmpeg
# Ubuntu: sudo apt install ffmpeg
# Windows: choco install ffmpeg
```
### 基本转录
```python
import whisper
# Load model
model = whisper.load_model("base")
# Transcribe
result = model.transcribe("audio.mp3")
# Print text
print(result["text"])
# Access segments
for segment in result["segments"]:
print(f"[{segment['start']:.2f}s - {segment['end']:.2f}s] {segment['text']}")
```
## 模型规格
```python
# Available models
models = ["tiny", "base", "small", "medium", "large", "turbo"]
# Load specific model
model = whisper.load_model("turbo") # Fastest, good quality
```
| 模型 | 参数量 | 仅英语 | 多语言 | 速度 | 显存 |
|-------|------------|--------------|--------------|-------|------|
| tiny | 39M | ✓ | ✓ | ~32x | ~1 GB |
| base | 74M | ✓ | ✓ | ~16x | ~1 GB |
| small | 244M | ✓ | ✓ | ~6x | ~2 GB |
| medium | 769M | ✓ | ✓ | ~2x | ~5 GB |
| large | 1550M | ✗ | ✓ | 1x | ~10 GB |
| turbo | 809M | ✗ | ✓ | ~8x | ~6 GB |
**推荐**:追求最佳速度/质量比使用 `turbo`,原型开发使用 `base`
## 转录选项
### 语言指定
```python
# Auto-detect language
result = model.transcribe("audio.mp3")
# Specify language (faster)
result = model.transcribe("audio.mp3", language="en")
# Supported: en, es, fr, de, it, pt, ru, ja, ko, zh, and 89 more
```
### 任务选择
```python
# Transcription (default)
result = model.transcribe("audio.mp3", task="transcribe")
# Translation to English
result = model.transcribe("spanish.mp3", task="translate")
# Input: Spanish audio → Output: English text
```
### 初始 prompt(提示词)
```python
# Improve accuracy with context
result = model.transcribe(
"audio.mp3",
initial_prompt="This is a technical podcast about machine learning and AI."
)
# Helps with:
# - Technical terms
# - Proper nouns
# - Domain-specific vocabulary
```
### 时间戳
```python
# Word-level timestamps
result = model.transcribe("audio.mp3", word_timestamps=True)
for segment in result["segments"]:
for word in segment["words"]:
print(f"{word['word']} ({word['start']:.2f}s - {word['end']:.2f}s)")
```
### 温度回退
```python
# Retry with different temperatures if confidence low
result = model.transcribe(
"audio.mp3",
temperature=(0.0, 0.2, 0.4, 0.6, 0.8, 1.0)
)
```
## 命令行用法
```bash
# Basic transcription
whisper audio.mp3
# Specify model
whisper audio.mp3 --model turbo
# Output formats
whisper audio.mp3 --output_format txt # Plain text
whisper audio.mp3 --output_format srt # Subtitles
whisper audio.mp3 --output_format vtt # WebVTT
whisper audio.mp3 --output_format json # JSON with timestamps
# Language
whisper audio.mp3 --language Spanish
# Translation
whisper spanish.mp3 --task translate
```
## 批量处理
```python
import os
audio_files = ["file1.mp3", "file2.mp3", "file3.mp3"]
for audio_file in audio_files:
print(f"Transcribing {audio_file}...")
result = model.transcribe(audio_file)
# Save to file
output_file = audio_file.replace(".mp3", ".txt")
with open(output_file, "w") as f:
f.write(result["text"])
```
## 实时转录
```python
# For streaming audio, use faster-whisper
# pip install faster-whisper
from faster_whisper import WhisperModel
model = WhisperModel("base", device="cuda", compute_type="float16")
# Transcribe with streaming
segments, info = model.transcribe("audio.mp3", beam_size=5)
for segment in segments:
print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
```
## GPU 加速
```python
import whisper
# Automatically uses GPU if available
model = whisper.load_model("turbo")
# Force CPU
model = whisper.load_model("turbo", device="cpu")
# Force GPU
model = whisper.load_model("turbo", device="cuda")
# 10-20× faster on GPU
```
## 与其他工具集成
### 字幕生成
```bash
# Generate SRT subtitles
whisper video.mp4 --output_format srt --language English
# Output: video.srt
```
### 与 LangChain 集成
```python
from langchain.document_loaders import WhisperTranscriptionLoader
loader = WhisperTranscriptionLoader(file_path="audio.mp3")
docs = loader.load()
# Use transcription in RAG
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())
```
### 从视频中提取音频
```bash
# Use ffmpeg to extract audio
ffmpeg -i video.mp4 -vn -acodec pcm_s16le audio.wav
# Then transcribe
whisper audio.wav
```
## 最佳实践
1. **使用 turbo 模型** — 英语场景下速度/质量最优
2. **指定语言** — 比自动检测更快
3. **添加初始 prompt** — 提升专业术语识别准确率
4. **使用 GPU** — 速度提升 1020 倍
5. **批量处理** — 效率更高
6. **转换为 WAV** — 兼容性更好
7. **切分长音频** — 每段不超过 30 分钟
8. **确认语言支持情况** — 不同语言质量有差异
9. **使用 faster-whisper** — 比 openai-whisper 快 4 倍
10. **监控显存** — 根据硬件配置选择模型规格
## 性能
| 模型 | 实时倍率(CPU) | 实时倍率(GPU) |
|-------|------------------------|------------------------|
| tiny | ~0.32 | ~0.01 |
| base | ~0.16 | ~0.01 |
| turbo | ~0.08 | ~0.01 |
| large | ~1.0 | ~0.05 |
*实时倍率:0.1 表示比实时速度快 10 倍*
## 语言支持
主要支持语言:
- 英语(en
- 西班牙语(es
- 法语(fr
- 德语(de
- 意大利语(it
- 葡萄牙语(pt
- 俄语(ru
- 日语(ja
- 韩语(ko
- 中文(zh
完整列表:共 99 种语言
## 局限性
1. **幻觉问题** — 可能重复或生成不存在的文本
2. **长音频准确率** — 超过 30 分钟后质量下降
3. **说话人识别** — 不支持说话人分离
4. **口音** — 质量因口音而异
5. **背景噪音** — 可能影响准确率
6. **实时延迟** — 不适合实时字幕场景
## 资源
- **GitHub**https://github.com/openai/whisper ⭐ 72,900+
- **论文**https://arxiv.org/abs/2212.04356
- **模型卡片**https://github.com/openai/whisper/blob/main/model-card.md
- **Colab**:可在仓库中获取
- **许可证**MIT