forked from Zakaria/hermes-agent
Hermes-agent
This commit is contained in:
+512
@@ -0,0 +1,512 @@
|
||||
---
|
||||
title: "Evaluating Llms Harness — lm-eval-harness: benchmark LLMs (MMLU, GSM8K, etc"
|
||||
sidebar_label: "Evaluating Llms Harness"
|
||||
description: "lm-eval-harness:对 LLM 进行基准测试(MMLU、GSM8K 等)"
|
||||
---
|
||||
|
||||
{/* 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. */}
|
||||
|
||||
# Evaluating Llms Harness
|
||||
|
||||
lm-eval-harness:对 LLM 进行基准测试(MMLU、GSM8K 等)。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/evaluation/lm-evaluation-harness` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖项 | `lm-eval`, `transformers`, `vllm` |
|
||||
| 平台 | linux, macos |
|
||||
| 标签 | `Evaluation`, `LM Evaluation Harness`, `Benchmarking`, `MMLU`, `HumanEval`, `GSM8K`, `EleutherAI`, `Model Quality`, `Academic Benchmarks`, `Industry Standard` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# lm-evaluation-harness - LLM 基准测试
|
||||
|
||||
## 内容概览
|
||||
|
||||
在 60+ 个学术基准(MMLU、HumanEval、GSM8K、TruthfulQA、HellaSwag)上评估 LLM。适用于基准测试模型质量、比较模型、报告学术结果或跟踪训练进度。行业标准工具,被 EleutherAI、HuggingFace 及各大实验室广泛使用。支持 HuggingFace、vLLM 及 API。
|
||||
|
||||
## 快速开始
|
||||
|
||||
lm-evaluation-harness 使用标准化 prompt(提示词)和指标,在 60+ 个学术基准上评估 LLM。
|
||||
|
||||
**安装**:
|
||||
```bash
|
||||
pip install lm-eval
|
||||
```
|
||||
|
||||
**评估任意 HuggingFace 模型**:
|
||||
```bash
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf \
|
||||
--tasks mmlu,gsm8k,hellaswag \
|
||||
--device cuda:0 \
|
||||
--batch_size 8
|
||||
```
|
||||
|
||||
**查看可用任务**:
|
||||
```bash
|
||||
lm_eval --tasks list
|
||||
```
|
||||
|
||||
## 常用工作流
|
||||
|
||||
### 工作流 1:标准基准评估
|
||||
|
||||
在核心基准(MMLU、GSM8K、HumanEval)上评估模型。
|
||||
|
||||
复制此检查清单:
|
||||
|
||||
```
|
||||
基准评估:
|
||||
- [ ] 步骤 1:选择基准套件
|
||||
- [ ] 步骤 2:配置模型
|
||||
- [ ] 步骤 3:运行评估
|
||||
- [ ] 步骤 4:分析结果
|
||||
```
|
||||
|
||||
**步骤 1:选择基准套件**
|
||||
|
||||
**核心推理基准**:
|
||||
- **MMLU**(Massive Multitask Language Understanding)- 57 个科目,多项选择
|
||||
- **GSM8K** - 小学数学应用题
|
||||
- **HellaSwag** - 常识推理
|
||||
- **TruthfulQA** - 真实性与事实性
|
||||
- **ARC**(AI2 Reasoning Challenge)- 科学题目
|
||||
|
||||
**代码基准**:
|
||||
- **HumanEval** - Python 代码生成(164 道题)
|
||||
- **MBPP**(Mostly Basic Python Problems)- Python 编程
|
||||
|
||||
**标准套件**(推荐用于模型发布):
|
||||
```bash
|
||||
--tasks mmlu,gsm8k,hellaswag,truthfulqa,arc_challenge
|
||||
```
|
||||
|
||||
**步骤 2:配置模型**
|
||||
|
||||
**HuggingFace 模型**:
|
||||
```bash
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf,dtype=bfloat16 \
|
||||
--tasks mmlu \
|
||||
--device cuda:0 \
|
||||
--batch_size auto # Auto-detect optimal batch size
|
||||
```
|
||||
|
||||
**量化模型(4-bit/8-bit)**:
|
||||
```bash
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf,load_in_4bit=True \
|
||||
--tasks mmlu \
|
||||
--device cuda:0
|
||||
```
|
||||
|
||||
**自定义 checkpoint**:
|
||||
```bash
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=/path/to/my-model,tokenizer=/path/to/tokenizer \
|
||||
--tasks mmlu \
|
||||
--device cuda:0
|
||||
```
|
||||
|
||||
**步骤 3:运行评估**
|
||||
|
||||
```bash
|
||||
# Full MMLU evaluation (57 subjects)
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf \
|
||||
--tasks mmlu \
|
||||
--num_fewshot 5 \ # 5-shot evaluation (standard)
|
||||
--batch_size 8 \
|
||||
--output_path results/ \
|
||||
--log_samples # Save individual predictions
|
||||
|
||||
# Multiple benchmarks at once
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf \
|
||||
--tasks mmlu,gsm8k,hellaswag,truthfulqa,arc_challenge \
|
||||
--num_fewshot 5 \
|
||||
--batch_size 8 \
|
||||
--output_path results/llama2-7b-eval.json
|
||||
```
|
||||
|
||||
**步骤 4:分析结果**
|
||||
|
||||
结果保存至 `results/llama2-7b-eval.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"results": {
|
||||
"mmlu": {
|
||||
"acc": 0.459,
|
||||
"acc_stderr": 0.004
|
||||
},
|
||||
"gsm8k": {
|
||||
"exact_match": 0.142,
|
||||
"exact_match_stderr": 0.006
|
||||
},
|
||||
"hellaswag": {
|
||||
"acc_norm": 0.765,
|
||||
"acc_norm_stderr": 0.004
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"model": "hf",
|
||||
"model_args": "pretrained=meta-llama/Llama-2-7b-hf",
|
||||
"num_fewshot": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 工作流 2:跟踪训练进度
|
||||
|
||||
在训练过程中评估 checkpoint。
|
||||
|
||||
```
|
||||
训练进度跟踪:
|
||||
- [ ] 步骤 1:设置定期评估
|
||||
- [ ] 步骤 2:选择快速基准
|
||||
- [ ] 步骤 3:自动化评估
|
||||
- [ ] 步骤 4:绘制学习曲线
|
||||
```
|
||||
|
||||
**步骤 1:设置定期评估**
|
||||
|
||||
每 N 个训练步骤评估一次:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# eval_checkpoint.sh
|
||||
|
||||
CHECKPOINT_DIR=$1
|
||||
STEP=$2
|
||||
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=$CHECKPOINT_DIR/checkpoint-$STEP \
|
||||
--tasks gsm8k,hellaswag \
|
||||
--num_fewshot 0 \ # 0-shot for speed
|
||||
--batch_size 16 \
|
||||
--output_path results/step-$STEP.json
|
||||
```
|
||||
|
||||
**步骤 2:选择快速基准**
|
||||
|
||||
适合频繁评估的快速基准:
|
||||
- **HellaSwag**:单 GPU 约 10 分钟
|
||||
- **GSM8K**:约 5 分钟
|
||||
- **PIQA**:约 2 分钟
|
||||
|
||||
不适合频繁评估(耗时过长):
|
||||
- **MMLU**:约 2 小时(57 个科目)
|
||||
- **HumanEval**:需要执行代码
|
||||
|
||||
**步骤 3:自动化评估**
|
||||
|
||||
集成到训练脚本中:
|
||||
|
||||
```python
|
||||
# In training loop
|
||||
if step % eval_interval == 0:
|
||||
model.save_pretrained(f"checkpoints/step-{step}")
|
||||
|
||||
# Run evaluation
|
||||
os.system(f"./eval_checkpoint.sh checkpoints step-{step}")
|
||||
```
|
||||
|
||||
或使用 PyTorch Lightning callback:
|
||||
|
||||
```python
|
||||
from pytorch_lightning import Callback
|
||||
|
||||
class EvalHarnessCallback(Callback):
|
||||
def on_validation_epoch_end(self, trainer, pl_module):
|
||||
step = trainer.global_step
|
||||
checkpoint_path = f"checkpoints/step-{step}"
|
||||
|
||||
# Save checkpoint
|
||||
trainer.save_checkpoint(checkpoint_path)
|
||||
|
||||
# Run lm-eval
|
||||
os.system(f"lm_eval --model hf --model_args pretrained={checkpoint_path} ...")
|
||||
```
|
||||
|
||||
**步骤 4:绘制学习曲线**
|
||||
|
||||
```python
|
||||
import json
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Load all results
|
||||
steps = []
|
||||
mmlu_scores = []
|
||||
|
||||
for file in sorted(glob.glob("results/step-*.json")):
|
||||
with open(file) as f:
|
||||
data = json.load(f)
|
||||
step = int(file.split("-")[1].split(".")[0])
|
||||
steps.append(step)
|
||||
mmlu_scores.append(data["results"]["mmlu"]["acc"])
|
||||
|
||||
# Plot
|
||||
plt.plot(steps, mmlu_scores)
|
||||
plt.xlabel("Training Step")
|
||||
plt.ylabel("MMLU Accuracy")
|
||||
plt.title("Training Progress")
|
||||
plt.savefig("training_curve.png")
|
||||
```
|
||||
|
||||
### 工作流 3:比较多个模型
|
||||
|
||||
用于模型比较的基准套件。
|
||||
|
||||
```
|
||||
模型比较:
|
||||
- [ ] 步骤 1:定义模型列表
|
||||
- [ ] 步骤 2:运行评估
|
||||
- [ ] 步骤 3:生成对比表格
|
||||
```
|
||||
|
||||
**步骤 1:定义模型列表**
|
||||
|
||||
```bash
|
||||
# models.txt
|
||||
meta-llama/Llama-2-7b-hf
|
||||
meta-llama/Llama-2-13b-hf
|
||||
mistralai/Mistral-7B-v0.1
|
||||
microsoft/phi-2
|
||||
```
|
||||
|
||||
**步骤 2:运行评估**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# eval_all_models.sh
|
||||
|
||||
TASKS="mmlu,gsm8k,hellaswag,truthfulqa"
|
||||
|
||||
while read model; do
|
||||
echo "Evaluating $model"
|
||||
|
||||
# Extract model name for output file
|
||||
model_name=$(echo $model | sed 's/\//-/g')
|
||||
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=$model,dtype=bfloat16 \
|
||||
--tasks $TASKS \
|
||||
--num_fewshot 5 \
|
||||
--batch_size auto \
|
||||
--output_path results/$model_name.json
|
||||
|
||||
done < models.txt
|
||||
```
|
||||
|
||||
**步骤 3:生成对比表格**
|
||||
|
||||
```python
|
||||
import json
|
||||
import pandas as pd
|
||||
|
||||
models = [
|
||||
"meta-llama-Llama-2-7b-hf",
|
||||
"meta-llama-Llama-2-13b-hf",
|
||||
"mistralai-Mistral-7B-v0.1",
|
||||
"microsoft-phi-2"
|
||||
]
|
||||
|
||||
tasks = ["mmlu", "gsm8k", "hellaswag", "truthfulqa"]
|
||||
|
||||
results = []
|
||||
for model in models:
|
||||
with open(f"results/{model}.json") as f:
|
||||
data = json.load(f)
|
||||
row = {"Model": model.replace("-", "/")}
|
||||
for task in tasks:
|
||||
# Get primary metric for each task
|
||||
metrics = data["results"][task]
|
||||
if "acc" in metrics:
|
||||
row[task.upper()] = f"{metrics['acc']:.3f}"
|
||||
elif "exact_match" in metrics:
|
||||
row[task.upper()] = f"{metrics['exact_match']:.3f}"
|
||||
results.append(row)
|
||||
|
||||
df = pd.DataFrame(results)
|
||||
print(df.to_markdown(index=False))
|
||||
```
|
||||
|
||||
输出:
|
||||
```
|
||||
| Model | MMLU | GSM8K | HELLASWAG | TRUTHFULQA |
|
||||
|------------------------|-------|-------|-----------|------------|
|
||||
| meta-llama/Llama-2-7b | 0.459 | 0.142 | 0.765 | 0.391 |
|
||||
| meta-llama/Llama-2-13b | 0.549 | 0.287 | 0.801 | 0.430 |
|
||||
| mistralai/Mistral-7B | 0.626 | 0.395 | 0.812 | 0.428 |
|
||||
| microsoft/phi-2 | 0.560 | 0.613 | 0.682 | 0.447 |
|
||||
```
|
||||
|
||||
### 工作流 4:使用 vLLM 评估(更快的推理)
|
||||
|
||||
使用 vLLM 后端可获得 5-10 倍的评估速度提升。
|
||||
|
||||
```
|
||||
vLLM 评估:
|
||||
- [ ] 步骤 1:安装 vLLM
|
||||
- [ ] 步骤 2:配置 vLLM 后端
|
||||
- [ ] 步骤 3:运行评估
|
||||
```
|
||||
|
||||
**步骤 1:安装 vLLM**
|
||||
|
||||
```bash
|
||||
pip install vllm
|
||||
```
|
||||
|
||||
**步骤 2:配置 vLLM 后端**
|
||||
|
||||
```bash
|
||||
lm_eval --model vllm \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf,tensor_parallel_size=1,dtype=auto,gpu_memory_utilization=0.8 \
|
||||
--tasks mmlu \
|
||||
--batch_size auto
|
||||
```
|
||||
|
||||
**步骤 3:运行评估**
|
||||
|
||||
vLLM 比标准 HuggingFace 快 5-10 倍:
|
||||
|
||||
```bash
|
||||
# Standard HF: ~2 hours for MMLU on 7B model
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf \
|
||||
--tasks mmlu \
|
||||
--batch_size 8
|
||||
|
||||
# vLLM: ~15-20 minutes for MMLU on 7B model
|
||||
lm_eval --model vllm \
|
||||
--model_args pretrained=meta-llama/Llama-2-7b-hf,tensor_parallel_size=2 \
|
||||
--tasks mmlu \
|
||||
--batch_size auto
|
||||
```
|
||||
|
||||
## 何时使用及替代方案
|
||||
|
||||
**在以下情况使用 lm-evaluation-harness:**
|
||||
- 为学术论文进行模型基准测试
|
||||
- 在标准任务上比较模型质量
|
||||
- 跟踪训练进度
|
||||
- 报告标准化指标(所有人使用相同 prompt)
|
||||
- 需要可复现的评估结果
|
||||
|
||||
**改用以下替代方案:**
|
||||
- **HELM**(Stanford):更广泛的评估(公平性、效率、校准)
|
||||
- **AlpacaEval**:使用 LLM 作为评判的指令跟随评估
|
||||
- **MT-Bench**:多轮对话评估
|
||||
- **自定义脚本**:特定领域评估
|
||||
|
||||
## 常见问题
|
||||
|
||||
**问题:评估速度过慢**
|
||||
|
||||
使用 vLLM 后端:
|
||||
```bash
|
||||
lm_eval --model vllm \
|
||||
--model_args pretrained=model-name,tensor_parallel_size=2
|
||||
```
|
||||
|
||||
或减少 few-shot 示例数:
|
||||
```bash
|
||||
--num_fewshot 0 # Instead of 5
|
||||
```
|
||||
|
||||
或评估 MMLU 子集:
|
||||
```bash
|
||||
--tasks mmlu_stem # Only STEM subjects
|
||||
```
|
||||
|
||||
**问题:显存不足**
|
||||
|
||||
减小 batch size:
|
||||
```bash
|
||||
--batch_size 1 # Or --batch_size auto
|
||||
```
|
||||
|
||||
使用量化:
|
||||
```bash
|
||||
--model_args pretrained=model-name,load_in_8bit=True
|
||||
```
|
||||
|
||||
启用 CPU offloading:
|
||||
```bash
|
||||
--model_args pretrained=model-name,device_map=auto,offload_folder=offload
|
||||
```
|
||||
|
||||
**问题:结果与已报告数值不一致**
|
||||
|
||||
检查 few-shot 数量:
|
||||
```bash
|
||||
--num_fewshot 5 # Most papers use 5-shot
|
||||
```
|
||||
|
||||
检查确切任务名称:
|
||||
```bash
|
||||
--tasks mmlu # Not mmlu_direct or mmlu_fewshot
|
||||
```
|
||||
|
||||
验证模型与 tokenizer 匹配:
|
||||
```bash
|
||||
--model_args pretrained=model-name,tokenizer=same-model-name
|
||||
```
|
||||
|
||||
**问题:HumanEval 未执行代码**
|
||||
|
||||
安装执行依赖:
|
||||
```bash
|
||||
pip install human-eval
|
||||
```
|
||||
|
||||
启用代码执行:
|
||||
```bash
|
||||
lm_eval --model hf \
|
||||
--model_args pretrained=model-name \
|
||||
--tasks humaneval \
|
||||
--allow_code_execution # Required for HumanEval
|
||||
```
|
||||
|
||||
## 进阶主题
|
||||
|
||||
**基准描述**:参见 [references/benchmark-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/evaluation/lm-evaluation-harness/references/benchmark-guide.md),了解所有 60+ 个任务的详细说明、测量内容及结果解读。
|
||||
|
||||
**自定义任务**:参见 [references/custom-tasks.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/evaluation/lm-evaluation-harness/references/custom-tasks.md),了解如何创建特定领域的评估任务。
|
||||
|
||||
**API 评估**:参见 [references/api-evaluation.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/evaluation/lm-evaluation-harness/references/api-evaluation.md),了解如何评估 OpenAI、Anthropic 及其他 API 模型。
|
||||
|
||||
**多 GPU 策略**:参见 [references/distributed-eval.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/evaluation/lm-evaluation-harness/references/distributed-eval.md),了解数据并行与张量并行评估方案。
|
||||
|
||||
## 硬件要求
|
||||
|
||||
- **GPU**:NVIDIA(CUDA 11.8+),支持 CPU 运行(速度极慢)
|
||||
- **显存**:
|
||||
- 7B 模型:16GB(bf16)或 8GB(8-bit)
|
||||
- 13B 模型:28GB(bf16)或 14GB(8-bit)
|
||||
- 70B 模型:需要多 GPU 或量化
|
||||
- **耗时**(7B 模型,单张 A100):
|
||||
- HellaSwag:10 分钟
|
||||
- GSM8K:5 分钟
|
||||
- MMLU(完整):2 小时
|
||||
- HumanEval:20 分钟
|
||||
|
||||
## 资源
|
||||
|
||||
- GitHub:https://github.com/EleutherAI/lm-evaluation-harness
|
||||
- 文档:https://github.com/EleutherAI/lm-evaluation-harness/tree/main/docs
|
||||
- 任务库:60+ 个任务,包括 MMLU、GSM8K、HumanEval、TruthfulQA、HellaSwag、ARC、WinoGrande 等
|
||||
- 排行榜:https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard(使用本工具)
|
||||
+609
@@ -0,0 +1,609 @@
|
||||
---
|
||||
title: "Weights And Biases — W&B:记录 ML 实验、sweeps、模型注册表、仪表盘"
|
||||
sidebar_label: "Weights And Biases"
|
||||
description: "W&B:记录 ML 实验、sweeps、模型注册表、仪表盘"
|
||||
---
|
||||
|
||||
{/* 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. */}
|
||||
|
||||
# Weights And Biases
|
||||
|
||||
W&B:记录 ML 实验、sweeps、模型注册表、仪表盘。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/evaluation/weights-and-biases` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖 | `wandb` |
|
||||
| 平台 | linux, macos, windows |
|
||||
| 标签 | `MLOps`, `Weights And Biases`, `WandB`, `Experiment Tracking`, `Hyperparameter Tuning`, `Model Registry`, `Collaboration`, `Real-Time Visualization`, `PyTorch`, `TensorFlow`, `HuggingFace` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# Weights & Biases:ML 实验追踪与 MLOps
|
||||
|
||||
## 适用场景
|
||||
|
||||
在以下情况下使用 Weights & Biases(W&B):
|
||||
- **追踪 ML 实验**,自动记录指标
|
||||
- **实时仪表盘可视化**训练过程
|
||||
- **跨超参数和配置对比运行结果**
|
||||
- **自动化 sweeps 优化超参数**
|
||||
- **管理模型注册表**,支持版本控制与血缘追踪
|
||||
- **团队协作开展 ML 项目**,共享工作区
|
||||
- **追踪 artifacts**(数据集、模型、代码)及其血缘关系
|
||||
|
||||
**用户数**:20 万+ ML 从业者 | **GitHub Stars**:10.5k+ | **集成数**:100+
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
# 安装 W&B
|
||||
pip install wandb
|
||||
|
||||
# 登录(创建 API key)
|
||||
wandb login
|
||||
|
||||
# 或以编程方式设置 API key
|
||||
export WANDB_API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 基础实验追踪
|
||||
|
||||
```python
|
||||
import wandb
|
||||
|
||||
# 初始化一次运行
|
||||
run = wandb.init(
|
||||
project="my-project",
|
||||
config={
|
||||
"learning_rate": 0.001,
|
||||
"epochs": 10,
|
||||
"batch_size": 32,
|
||||
"architecture": "ResNet50"
|
||||
}
|
||||
)
|
||||
|
||||
# 训练循环
|
||||
for epoch in range(run.config.epochs):
|
||||
# 你的训练代码
|
||||
train_loss = train_epoch()
|
||||
val_loss = validate()
|
||||
|
||||
# 记录指标
|
||||
wandb.log({
|
||||
"epoch": epoch,
|
||||
"train/loss": train_loss,
|
||||
"val/loss": val_loss,
|
||||
"train/accuracy": train_acc,
|
||||
"val/accuracy": val_acc
|
||||
})
|
||||
|
||||
# 结束运行
|
||||
wandb.finish()
|
||||
```
|
||||
|
||||
### 与 PyTorch 配合使用
|
||||
|
||||
```python
|
||||
import torch
|
||||
import wandb
|
||||
|
||||
# 初始化
|
||||
wandb.init(project="pytorch-demo", config={
|
||||
"lr": 0.001,
|
||||
"epochs": 10
|
||||
})
|
||||
|
||||
# 访问配置
|
||||
config = wandb.config
|
||||
|
||||
# 训练循环
|
||||
for epoch in range(config.epochs):
|
||||
for batch_idx, (data, target) in enumerate(train_loader):
|
||||
# 前向传播
|
||||
output = model(data)
|
||||
loss = criterion(output, target)
|
||||
|
||||
# 反向传播
|
||||
optimizer.zero_grad()
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
# 每 100 个 batch 记录一次
|
||||
if batch_idx % 100 == 0:
|
||||
wandb.log({
|
||||
"loss": loss.item(),
|
||||
"epoch": epoch,
|
||||
"batch": batch_idx
|
||||
})
|
||||
|
||||
# 保存模型
|
||||
torch.save(model.state_dict(), "model.pth")
|
||||
wandb.save("model.pth") # 上传至 W&B
|
||||
|
||||
wandb.finish()
|
||||
```
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 1. Projects 与 Runs
|
||||
|
||||
**Project**:相关实验的集合
|
||||
**Run**:训练脚本的单次执行
|
||||
|
||||
```python
|
||||
# 创建/使用 project
|
||||
run = wandb.init(
|
||||
project="image-classification",
|
||||
name="resnet50-experiment-1", # 可选的运行名称
|
||||
tags=["baseline", "resnet"], # 使用标签组织
|
||||
notes="First baseline run" # 添加备注
|
||||
)
|
||||
|
||||
# 每次运行都有唯一 ID
|
||||
print(f"Run ID: {run.id}")
|
||||
print(f"Run URL: {run.url}")
|
||||
```
|
||||
|
||||
### 2. 配置追踪
|
||||
|
||||
自动追踪超参数:
|
||||
|
||||
```python
|
||||
config = {
|
||||
# 模型架构
|
||||
"model": "ResNet50",
|
||||
"pretrained": True,
|
||||
|
||||
# 训练参数
|
||||
"learning_rate": 0.001,
|
||||
"batch_size": 32,
|
||||
"epochs": 50,
|
||||
"optimizer": "Adam",
|
||||
|
||||
# 数据参数
|
||||
"dataset": "ImageNet",
|
||||
"augmentation": "standard"
|
||||
}
|
||||
|
||||
wandb.init(project="my-project", config=config)
|
||||
|
||||
# 训练过程中访问配置
|
||||
lr = wandb.config.learning_rate
|
||||
batch_size = wandb.config.batch_size
|
||||
```
|
||||
|
||||
### 3. 指标记录
|
||||
|
||||
```python
|
||||
# 记录标量
|
||||
wandb.log({"loss": 0.5, "accuracy": 0.92})
|
||||
|
||||
# 记录多个指标
|
||||
wandb.log({
|
||||
"train/loss": train_loss,
|
||||
"train/accuracy": train_acc,
|
||||
"val/loss": val_loss,
|
||||
"val/accuracy": val_acc,
|
||||
"learning_rate": current_lr,
|
||||
"epoch": epoch
|
||||
})
|
||||
|
||||
# 使用自定义 x 轴记录
|
||||
wandb.log({"loss": loss}, step=global_step)
|
||||
|
||||
# 记录媒体(图像、音频、视频)
|
||||
wandb.log({"examples": [wandb.Image(img) for img in images]})
|
||||
|
||||
# 记录直方图
|
||||
wandb.log({"gradients": wandb.Histogram(gradients)})
|
||||
|
||||
# 记录表格
|
||||
table = wandb.Table(columns=["id", "prediction", "ground_truth"])
|
||||
wandb.log({"predictions": table})
|
||||
```
|
||||
|
||||
### 4. 模型检查点
|
||||
|
||||
```python
|
||||
import torch
|
||||
import wandb
|
||||
|
||||
# 保存模型检查点
|
||||
checkpoint = {
|
||||
'epoch': epoch,
|
||||
'model_state_dict': model.state_dict(),
|
||||
'optimizer_state_dict': optimizer.state_dict(),
|
||||
'loss': loss,
|
||||
}
|
||||
|
||||
torch.save(checkpoint, 'checkpoint.pth')
|
||||
|
||||
# 上传至 W&B
|
||||
wandb.save('checkpoint.pth')
|
||||
|
||||
# 或使用 Artifacts(推荐)
|
||||
artifact = wandb.Artifact('model', type='model')
|
||||
artifact.add_file('checkpoint.pth')
|
||||
wandb.log_artifact(artifact)
|
||||
```
|
||||
|
||||
## 超参数 Sweeps
|
||||
|
||||
自动搜索最优超参数。
|
||||
|
||||
### 定义 Sweep 配置
|
||||
|
||||
```python
|
||||
sweep_config = {
|
||||
'method': 'bayes', # 或 'grid'、'random'
|
||||
'metric': {
|
||||
'name': 'val/accuracy',
|
||||
'goal': 'maximize'
|
||||
},
|
||||
'parameters': {
|
||||
'learning_rate': {
|
||||
'distribution': 'log_uniform',
|
||||
'min': 1e-5,
|
||||
'max': 1e-1
|
||||
},
|
||||
'batch_size': {
|
||||
'values': [16, 32, 64, 128]
|
||||
},
|
||||
'optimizer': {
|
||||
'values': ['adam', 'sgd', 'rmsprop']
|
||||
},
|
||||
'dropout': {
|
||||
'distribution': 'uniform',
|
||||
'min': 0.1,
|
||||
'max': 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 初始化 sweep
|
||||
sweep_id = wandb.sweep(sweep_config, project="my-project")
|
||||
```
|
||||
|
||||
### 定义训练函数
|
||||
|
||||
```python
|
||||
def train():
|
||||
# 初始化运行
|
||||
run = wandb.init()
|
||||
|
||||
# 访问 sweep 参数
|
||||
lr = wandb.config.learning_rate
|
||||
batch_size = wandb.config.batch_size
|
||||
optimizer_name = wandb.config.optimizer
|
||||
|
||||
# 使用 sweep 配置构建模型
|
||||
model = build_model(wandb.config)
|
||||
optimizer = get_optimizer(optimizer_name, lr)
|
||||
|
||||
# 训练循环
|
||||
for epoch in range(NUM_EPOCHS):
|
||||
train_loss = train_epoch(model, optimizer, batch_size)
|
||||
val_acc = validate(model)
|
||||
|
||||
# 记录指标
|
||||
wandb.log({
|
||||
"train/loss": train_loss,
|
||||
"val/accuracy": val_acc
|
||||
})
|
||||
|
||||
# 运行 sweep
|
||||
wandb.agent(sweep_id, function=train, count=50) # 运行 50 次试验
|
||||
```
|
||||
|
||||
### Sweep 策略
|
||||
|
||||
```python
|
||||
# 网格搜索 - 穷举
|
||||
sweep_config = {
|
||||
'method': 'grid',
|
||||
'parameters': {
|
||||
'lr': {'values': [0.001, 0.01, 0.1]},
|
||||
'batch_size': {'values': [16, 32, 64]}
|
||||
}
|
||||
}
|
||||
|
||||
# 随机搜索
|
||||
sweep_config = {
|
||||
'method': 'random',
|
||||
'parameters': {
|
||||
'lr': {'distribution': 'uniform', 'min': 0.0001, 'max': 0.1},
|
||||
'dropout': {'distribution': 'uniform', 'min': 0.1, 'max': 0.5}
|
||||
}
|
||||
}
|
||||
|
||||
# 贝叶斯优化(推荐)
|
||||
sweep_config = {
|
||||
'method': 'bayes',
|
||||
'metric': {'name': 'val/loss', 'goal': 'minimize'},
|
||||
'parameters': {
|
||||
'lr': {'distribution': 'log_uniform', 'min': 1e-5, 'max': 1e-1}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Artifacts
|
||||
|
||||
追踪数据集、模型及其他文件的血缘关系。
|
||||
|
||||
### 记录 Artifacts
|
||||
|
||||
```python
|
||||
# 创建 artifact
|
||||
artifact = wandb.Artifact(
|
||||
name='training-dataset',
|
||||
type='dataset',
|
||||
description='ImageNet training split',
|
||||
metadata={'size': '1.2M images', 'split': 'train'}
|
||||
)
|
||||
|
||||
# 添加文件
|
||||
artifact.add_file('data/train.csv')
|
||||
artifact.add_dir('data/images/')
|
||||
|
||||
# 记录 artifact
|
||||
wandb.log_artifact(artifact)
|
||||
```
|
||||
|
||||
### 使用 Artifacts
|
||||
|
||||
```python
|
||||
# 下载并使用 artifact
|
||||
run = wandb.init(project="my-project")
|
||||
|
||||
# 下载 artifact
|
||||
artifact = run.use_artifact('training-dataset:latest')
|
||||
artifact_dir = artifact.download()
|
||||
|
||||
# 使用数据
|
||||
data = load_data(f"{artifact_dir}/train.csv")
|
||||
```
|
||||
|
||||
### 模型注册表
|
||||
|
||||
```python
|
||||
# 将模型记录为 artifact
|
||||
model_artifact = wandb.Artifact(
|
||||
name='resnet50-model',
|
||||
type='model',
|
||||
metadata={'architecture': 'ResNet50', 'accuracy': 0.95}
|
||||
)
|
||||
|
||||
model_artifact.add_file('model.pth')
|
||||
wandb.log_artifact(model_artifact, aliases=['best', 'production'])
|
||||
|
||||
# 链接到模型注册表
|
||||
run.link_artifact(model_artifact, 'model-registry/production-models')
|
||||
```
|
||||
|
||||
## 集成示例
|
||||
|
||||
### HuggingFace Transformers
|
||||
|
||||
```python
|
||||
from transformers import Trainer, TrainingArguments
|
||||
import wandb
|
||||
|
||||
# 初始化 W&B
|
||||
wandb.init(project="hf-transformers")
|
||||
|
||||
# 带 W&B 的训练参数
|
||||
training_args = TrainingArguments(
|
||||
output_dir="./results",
|
||||
report_to="wandb", # 启用 W&B 日志
|
||||
run_name="bert-finetuning",
|
||||
logging_steps=100,
|
||||
save_steps=500
|
||||
)
|
||||
|
||||
# Trainer 自动记录至 W&B
|
||||
trainer = Trainer(
|
||||
model=model,
|
||||
args=training_args,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset
|
||||
)
|
||||
|
||||
trainer.train()
|
||||
```
|
||||
|
||||
### PyTorch Lightning
|
||||
|
||||
```python
|
||||
from pytorch_lightning import Trainer
|
||||
from pytorch_lightning.loggers import WandbLogger
|
||||
import wandb
|
||||
|
||||
# 创建 W&B logger
|
||||
wandb_logger = WandbLogger(
|
||||
project="lightning-demo",
|
||||
log_model=True # 记录模型检查点
|
||||
)
|
||||
|
||||
# 与 Trainer 配合使用
|
||||
trainer = Trainer(
|
||||
logger=wandb_logger,
|
||||
max_epochs=10
|
||||
)
|
||||
|
||||
trainer.fit(model, datamodule=dm)
|
||||
```
|
||||
|
||||
### Keras/TensorFlow
|
||||
|
||||
```python
|
||||
import wandb
|
||||
from wandb.keras import WandbCallback
|
||||
|
||||
# 初始化
|
||||
wandb.init(project="keras-demo")
|
||||
|
||||
# 添加回调
|
||||
model.fit(
|
||||
x_train, y_train,
|
||||
validation_data=(x_val, y_val),
|
||||
epochs=10,
|
||||
callbacks=[WandbCallback()] # 自动记录指标
|
||||
)
|
||||
```
|
||||
|
||||
## 可视化与分析
|
||||
|
||||
### 自定义图表
|
||||
|
||||
```python
|
||||
# 记录自定义可视化
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(x, y)
|
||||
wandb.log({"custom_plot": wandb.Image(fig)})
|
||||
|
||||
# 记录混淆矩阵
|
||||
wandb.log({"conf_mat": wandb.plot.confusion_matrix(
|
||||
probs=None,
|
||||
y_true=ground_truth,
|
||||
preds=predictions,
|
||||
class_names=class_names
|
||||
)})
|
||||
```
|
||||
|
||||
### Reports
|
||||
|
||||
在 W&B UI 中创建可分享的报告:
|
||||
- 组合运行结果、图表与文本
|
||||
- 支持 Markdown
|
||||
- 可嵌入的可视化内容
|
||||
- 团队协作
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 使用标签和分组进行组织
|
||||
|
||||
```python
|
||||
wandb.init(
|
||||
project="my-project",
|
||||
tags=["baseline", "resnet50", "imagenet"],
|
||||
group="resnet-experiments", # 对相关运行分组
|
||||
job_type="train" # 任务类型
|
||||
)
|
||||
```
|
||||
|
||||
### 2. 记录所有相关信息
|
||||
|
||||
```python
|
||||
# 记录系统指标
|
||||
wandb.log({
|
||||
"gpu/util": gpu_utilization,
|
||||
"gpu/memory": gpu_memory_used,
|
||||
"cpu/util": cpu_utilization
|
||||
})
|
||||
|
||||
# 记录代码版本
|
||||
wandb.log({"git_commit": git_commit_hash})
|
||||
|
||||
# 记录数据划分
|
||||
wandb.log({
|
||||
"data/train_size": len(train_dataset),
|
||||
"data/val_size": len(val_dataset)
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 使用描述性名称
|
||||
|
||||
```python
|
||||
# ✅ 好:描述性运行名称
|
||||
wandb.init(
|
||||
project="nlp-classification",
|
||||
name="bert-base-lr0.001-bs32-epoch10"
|
||||
)
|
||||
|
||||
# ❌ 差:通用名称
|
||||
wandb.init(project="nlp", name="run1")
|
||||
```
|
||||
|
||||
### 4. 保存重要 Artifacts
|
||||
|
||||
```python
|
||||
# 保存最终模型
|
||||
artifact = wandb.Artifact('final-model', type='model')
|
||||
artifact.add_file('model.pth')
|
||||
wandb.log_artifact(artifact)
|
||||
|
||||
# 保存预测结果以供分析
|
||||
predictions_table = wandb.Table(
|
||||
columns=["id", "input", "prediction", "ground_truth"],
|
||||
data=predictions_data
|
||||
)
|
||||
wandb.log({"predictions": predictions_table})
|
||||
```
|
||||
|
||||
### 5. 在网络不稳定时使用离线模式
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
# 启用离线模式
|
||||
os.environ["WANDB_MODE"] = "offline"
|
||||
|
||||
wandb.init(project="my-project")
|
||||
# ... 你的代码 ...
|
||||
|
||||
# 稍后同步
|
||||
# wandb sync <run_directory>
|
||||
```
|
||||
|
||||
## 团队协作
|
||||
|
||||
### 分享运行结果
|
||||
|
||||
```python
|
||||
# 运行结果可通过 URL 自动分享
|
||||
run = wandb.init(project="team-project")
|
||||
print(f"Share this URL: {run.url}")
|
||||
```
|
||||
|
||||
### 团队项目
|
||||
|
||||
- 在 wandb.ai 创建团队账号
|
||||
- 添加团队成员
|
||||
- 设置项目可见性(私有/公开)
|
||||
- 使用团队级 artifacts 和模型注册表
|
||||
|
||||
## 定价
|
||||
|
||||
- **免费版**:无限公开项目,100GB 存储
|
||||
- **学术版**:学生/研究人员免费使用
|
||||
- **团队版**:$50/席位/月,私有项目,无限存储
|
||||
- **企业版**:定制定价,支持本地部署
|
||||
|
||||
## 资源
|
||||
|
||||
- **文档**:https://docs.wandb.ai
|
||||
- **GitHub**:https://github.com/wandb/wandb(10.5k+ stars)
|
||||
- **示例**:https://github.com/wandb/examples
|
||||
- **社区**:https://wandb.ai/community
|
||||
- **Discord**:https://wandb.me/discord
|
||||
|
||||
## 另请参阅
|
||||
|
||||
- `references/sweeps.md` — 超参数优化综合指南
|
||||
- `references/artifacts.md` — 数据与模型版本控制模式
|
||||
- `references/integrations.md` — 框架专项示例
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: "Huggingface Hub — HuggingFace hf CLI:搜索/下载/上传模型、数据集"
|
||||
sidebar_label: "Huggingface Hub"
|
||||
description: "HuggingFace hf CLI:搜索/下载/上传模型、数据集"
|
||||
---
|
||||
|
||||
{/* 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 Hub
|
||||
|
||||
HuggingFace hf CLI:搜索/下载/上传模型、数据集。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/huggingface-hub` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Hugging Face |
|
||||
| 许可证 | MIT |
|
||||
| 平台 | linux, macos, windows |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
|
||||
:::
|
||||
|
||||
# Hugging Face CLI(`hf`)参考指南
|
||||
|
||||
`hf` 命令是与 Hugging Face Hub 交互的现代命令行界面,提供管理仓库、模型、数据集和 Spaces 的工具。
|
||||
|
||||
> **重要:** `hf` 命令取代了现已弃用的 `huggingface-cli` 命令。
|
||||
|
||||
## 快速开始
|
||||
* **安装:** `curl -LsSf https://hf.co/cli/install.sh | bash -s`
|
||||
* **帮助:** 使用 `hf --help` 查看所有可用功能及实际示例。
|
||||
* **认证:** 推荐通过 `HF_TOKEN` 环境变量或 `--token` 标志进行认证。
|
||||
|
||||
---
|
||||
|
||||
## 核心命令
|
||||
|
||||
### 通用操作
|
||||
* `hf download REPO_ID`:从 Hub 下载文件。
|
||||
* `hf upload REPO_ID`:上传文件/文件夹(推荐用于单次提交)。
|
||||
* `hf upload-large-folder REPO_ID LOCAL_PATH`:推荐用于大型目录的可恢复上传。
|
||||
* `hf sync`:在本地目录与存储桶之间同步文件。
|
||||
* `hf env` / `hf version`:查看环境和版本详情。
|
||||
|
||||
### 认证(`hf auth`)
|
||||
* `login` / `logout`:使用来自 [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) 的 token 管理会话。
|
||||
* `list` / `switch`:管理并切换多个已存储的访问 token。
|
||||
* `whoami`:查看当前登录账户。
|
||||
|
||||
### 仓库管理(`hf repos`)
|
||||
* `create` / `delete`:创建或永久删除仓库。
|
||||
* `duplicate`:将模型、数据集或 Space 克隆到新 ID。
|
||||
* `move`:在命名空间之间迁移仓库。
|
||||
* `branch` / `tag`:管理类 Git 引用。
|
||||
* `delete-files`:使用模式匹配删除特定文件。
|
||||
|
||||
---
|
||||
|
||||
## 专项 Hub 交互
|
||||
|
||||
### 数据集与模型
|
||||
* **数据集:** `hf datasets list`、`info` 以及 `parquet`(列出 parquet URL)。
|
||||
* **SQL 查询:** `hf datasets sql SQL` — 通过 DuckDB 对数据集 parquet URL 执行原始 SQL。
|
||||
* **模型:** `hf models list` 和 `info`。
|
||||
* **论文:** `hf papers list` — 查看每日论文。
|
||||
|
||||
### 讨论与 Pull Request(`hf discussions`)
|
||||
* 管理 Hub 贡献的完整生命周期:`list`、`create`、`info`、`comment`、`close`、`reopen` 和 `rename`。
|
||||
* `diff`:查看 PR 中的变更。
|
||||
* `merge`:完成 pull request 合并。
|
||||
|
||||
### 基础设施与计算
|
||||
* **Endpoints:** 部署和管理推理端点(`deploy`、`pause`、`resume`、`scale-to-zero`、`catalog`)。
|
||||
* **Jobs:** 在 HF 基础设施上运行计算任务。包括 `hf jobs uv`(用于运行带内联依赖的 Python 脚本)和 `stats`(用于资源监控)。
|
||||
* **Spaces:** 管理交互式应用。包括 `dev-mode` 和 `hot-reload`,可在不完全重启的情况下热更新 Python 文件。
|
||||
|
||||
### 存储与自动化
|
||||
* **Buckets:** 完整的类 S3 存储桶管理(`create`、`cp`、`mv`、`rm`、`sync`)。
|
||||
* **Cache(缓存):** 使用 `list`、`prune`(删除已分离的修订版本)和 `verify`(校验和检查)管理本地存储。
|
||||
* **Webhooks:** 通过管理 Hub webhook(`create`、`watch`、`enable`/`disable`)自动化工作流。
|
||||
* **Collections:** 将 Hub 条目整理到集合中(`add-item`、`update`、`list`)。
|
||||
|
||||
---
|
||||
|
||||
## 高级用法与技巧
|
||||
|
||||
### 全局标志
|
||||
* `--format json`:生成适合自动化的机器可读输出。
|
||||
* `-q` / `--quiet`:将输出限制为仅显示 ID。
|
||||
|
||||
### 扩展与 Skills
|
||||
* **扩展:** 通过 GitHub 仓库使用 `hf extensions install REPO_ID` 扩展 CLI 功能。
|
||||
* **Skills:** 使用 `hf skills add` 管理 AI 助手 skill。
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
---
|
||||
title: "Llama Cpp — llama"
|
||||
sidebar_label: "Llama Cpp"
|
||||
description: "llama"
|
||||
---
|
||||
|
||||
{/* 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. */}
|
||||
|
||||
# Llama Cpp
|
||||
|
||||
llama.cpp 本地 GGUF 推理 + HF Hub 模型发现。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/inference/llama-cpp` |
|
||||
| 版本 | `2.1.2` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖 | `llama-cpp-python>=0.2.0` |
|
||||
| 平台 | linux, macos, windows |
|
||||
| 标签 | `llama.cpp`, `GGUF`, `Quantization`, `Hugging Face Hub`, `CPU Inference`, `Apple Silicon`, `Edge Deployment`, `AMD GPUs`, `Intel GPUs`, `NVIDIA`, `URL-first` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# llama.cpp + GGUF
|
||||
|
||||
本 skill 用于本地 GGUF 推理、量化(Quantization)选择,以及 Hugging Face 仓库发现(用于 llama.cpp)。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 在 CPU、Apple Silicon、CUDA、ROCm 或 Intel GPU 上运行本地模型
|
||||
- 为特定 Hugging Face 仓库找到合适的 GGUF 文件
|
||||
- 从 Hub 构建 `llama-server` 或 `llama-cli` 命令
|
||||
- 在 Hub 上搜索已支持 llama.cpp 的模型
|
||||
- 枚举某个仓库中可用的 `.gguf` 文件及其大小
|
||||
- 根据用户的 RAM 或 VRAM 在 Q4/Q5/Q6/IQ 变体之间做出选择
|
||||
|
||||
## 模型发现工作流
|
||||
|
||||
优先使用 URL 工作流,再考虑 `hf`、Python 或自定义脚本。
|
||||
|
||||
1. 在 Hub 上搜索候选仓库:
|
||||
- 基础地址:`https://huggingface.co/models?apps=llama.cpp&sort=trending`
|
||||
- 添加 `search=<term>` 以搜索特定模型系列
|
||||
- 当用户有参数量限制时,添加 `num_parameters=min:0,max:24B` 或类似参数
|
||||
2. 使用 llama.cpp 本地应用视图打开仓库:
|
||||
- `https://huggingface.co/<repo>?local-app=llama.cpp`
|
||||
3. 当 local-app 代码片段可见时,将其作为权威来源:
|
||||
- 复制完整的 `llama-server` 或 `llama-cli` 命令
|
||||
- 严格按照 HF 显示的推荐量化标签进行报告
|
||||
4. 将同一 `?local-app=llama.cpp` URL 作为页面文本或 HTML 读取,并提取 `Hardware compatibility` 部分:
|
||||
- 优先使用其中的精确量化标签和大小,而非通用表格
|
||||
- 保留仓库特有的标签,如 `UD-Q4_K_M` 或 `IQ4_NL_XL`
|
||||
- 如果该部分在获取的页面源码中不可见,请说明并回退到 tree API 加通用量化指导
|
||||
5. 查询 tree API 以确认实际存在的文件:
|
||||
- `https://huggingface.co/api/models/<repo>/tree/main?recursive=true`
|
||||
- 保留 `type` 为 `file` 且 `path` 以 `.gguf` 结尾的条目
|
||||
- 以 `path` 和 `size` 作为文件名和字节大小的权威来源
|
||||
- 将量化检查点与 `mmproj-*.gguf` 投影文件及 `BF16/` 分片文件分开处理
|
||||
- 仅将 `https://huggingface.co/<repo>/tree/main` 作为人工备用方案
|
||||
6. 如果 local-app 代码片段不可见,则从仓库和所选量化重建命令:
|
||||
- 简写量化选择:`llama-server -hf <repo>:<QUANT>`
|
||||
- 精确文件备用:`llama-server --hf-repo <repo> --hf-file <filename.gguf>`
|
||||
7. 仅当仓库未暴露 GGUF 文件时,才建议从 Transformers 权重进行转换。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装 llama.cpp
|
||||
|
||||
```bash
|
||||
# macOS / Linux(最简方式)
|
||||
brew install llama.cpp
|
||||
```
|
||||
|
||||
```bash
|
||||
winget install llama.cpp
|
||||
```
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ggml-org/llama.cpp
|
||||
cd llama.cpp
|
||||
cmake -B build
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
### 直接从 Hugging Face Hub 运行
|
||||
|
||||
```bash
|
||||
llama-cli -hf bartowski/Llama-3.2-3B-Instruct-GGUF:Q8_0
|
||||
```
|
||||
|
||||
```bash
|
||||
llama-server -hf bartowski/Llama-3.2-3B-Instruct-GGUF:Q8_0
|
||||
```
|
||||
|
||||
### 从 Hub 运行精确的 GGUF 文件
|
||||
|
||||
当 tree API 显示自定义文件命名或缺少精确 HF 代码片段时使用此方式。
|
||||
|
||||
```bash
|
||||
llama-server \
|
||||
--hf-repo microsoft/Phi-3-mini-4k-instruct-gguf \
|
||||
--hf-file Phi-3-mini-4k-instruct-q4.gguf \
|
||||
-c 4096
|
||||
```
|
||||
|
||||
### OpenAI 兼容服务器检查
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"messages": [
|
||||
{"role": "user", "content": "Write a limerick about Python exceptions"}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
## Python 绑定(llama-cpp-python)
|
||||
|
||||
`pip install llama-cpp-python`(CUDA:`CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python --force-reinstall --no-cache-dir`;Metal:`CMAKE_ARGS="-DGGML_METAL=on" ...`)。
|
||||
|
||||
### 基础生成
|
||||
|
||||
```python
|
||||
from llama_cpp import Llama
|
||||
|
||||
llm = Llama(
|
||||
model_path="./model-q4_k_m.gguf",
|
||||
n_ctx=4096,
|
||||
n_gpu_layers=35, # 0 为 CPU,99 为全部卸载到 GPU
|
||||
n_threads=8,
|
||||
)
|
||||
|
||||
out = llm("What is machine learning?", max_tokens=256, temperature=0.7)
|
||||
print(out["choices"][0]["text"])
|
||||
```
|
||||
|
||||
### 对话 + 流式输出
|
||||
|
||||
```python
|
||||
llm = Llama(
|
||||
model_path="./model-q4_k_m.gguf",
|
||||
n_ctx=4096,
|
||||
n_gpu_layers=35,
|
||||
chat_format="llama-3", # 或 "chatml"、"mistral" 等
|
||||
)
|
||||
|
||||
resp = llm.create_chat_completion(
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
{"role": "user", "content": "What is Python?"},
|
||||
],
|
||||
max_tokens=256,
|
||||
)
|
||||
print(resp["choices"][0]["message"]["content"])
|
||||
|
||||
# 流式输出
|
||||
for chunk in llm("Explain quantum computing:", max_tokens=256, stream=True):
|
||||
print(chunk["choices"][0]["text"], end="", flush=True)
|
||||
```
|
||||
|
||||
### Embedding(嵌入向量)
|
||||
|
||||
```python
|
||||
llm = Llama(model_path="./model-q4_k_m.gguf", embedding=True, n_gpu_layers=35)
|
||||
vec = llm.embed("This is a test sentence.")
|
||||
print(f"Embedding dimension: {len(vec)}")
|
||||
```
|
||||
|
||||
也可以直接从 Hub 加载 GGUF:
|
||||
|
||||
```python
|
||||
llm = Llama.from_pretrained(
|
||||
repo_id="bartowski/Llama-3.2-3B-Instruct-GGUF",
|
||||
filename="*Q4_K_M.gguf",
|
||||
n_gpu_layers=35,
|
||||
)
|
||||
```
|
||||
|
||||
## 选择量化方案
|
||||
|
||||
优先参考 Hub 页面,其次使用通用启发式规则。
|
||||
|
||||
- 优先使用 HF 标记为与用户硬件配置兼容的精确量化方案。
|
||||
- 一般对话场景,从 `Q4_K_M` 开始。
|
||||
- 代码或技术工作,若内存允许,优先选择 `Q5_K_M` 或 `Q6_K`。
|
||||
- RAM 非常紧张时,仅在用户明确将适配性置于质量之上时,才考虑 `Q3_K_M`、`IQ` 变体或 `Q2` 变体。
|
||||
- 对于多模态仓库,单独说明 `mmproj-*.gguf`。投影文件不是主模型文件。
|
||||
- 不要规范化仓库原生标签。如果页面显示 `UD-Q4_K_M`,就报告 `UD-Q4_K_M`。
|
||||
|
||||
## 从仓库提取可用的 GGUF 文件
|
||||
|
||||
当用户询问存在哪些 GGUF 时,返回:
|
||||
|
||||
- 文件名
|
||||
- 文件大小
|
||||
- 量化标签
|
||||
- 是否为主模型或辅助投影文件
|
||||
|
||||
除非被要求,否则忽略:
|
||||
|
||||
- README
|
||||
- BF16 分片文件
|
||||
- imatrix blob 或校准产物
|
||||
|
||||
此步骤使用 tree API:
|
||||
|
||||
- `https://huggingface.co/api/models/<repo>/tree/main?recursive=true`
|
||||
|
||||
对于 `unsloth/Qwen3.6-35B-A3B-GGUF` 这样的仓库,local-app 页面可显示 `UD-Q4_K_M`、`UD-Q5_K_M`、`UD-Q6_K` 和 `Q8_0` 等量化标签,而 tree API 则暴露精确文件路径(如 `Qwen3.6-35B-A3B-UD-Q4_K_M.gguf` 和 `Qwen3.6-35B-A3B-Q8_0.gguf`)及字节大小。使用 tree API 将量化标签转换为精确文件名。
|
||||
|
||||
## 搜索模式
|
||||
|
||||
直接使用以下 URL 格式:
|
||||
|
||||
```text
|
||||
https://huggingface.co/models?apps=llama.cpp&sort=trending
|
||||
https://huggingface.co/models?search=<term>&apps=llama.cpp&sort=trending
|
||||
https://huggingface.co/models?search=<term>&apps=llama.cpp&num_parameters=min:0,max:24B&sort=trending
|
||||
https://huggingface.co/<repo>?local-app=llama.cpp
|
||||
https://huggingface.co/api/models/<repo>/tree/main?recursive=true
|
||||
https://huggingface.co/<repo>/tree/main
|
||||
```
|
||||
|
||||
## 输出格式
|
||||
|
||||
回答发现请求时,优先使用如下紧凑结构化结果:
|
||||
|
||||
```text
|
||||
Repo: <repo>
|
||||
Recommended quant from HF: <label> (<size>)
|
||||
llama-server: <command>
|
||||
Other GGUFs:
|
||||
- <filename> - <size>
|
||||
- <filename> - <size>
|
||||
Source URLs:
|
||||
- <local-app URL>
|
||||
- <tree API URL>
|
||||
```
|
||||
|
||||
## 参考资料
|
||||
|
||||
- **[hub-discovery.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/hub-discovery.md)** — 纯 URL Hugging Face 工作流、搜索模式、GGUF 提取及命令重建
|
||||
- **[advanced-usage.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/advanced-usage.md)** — 推测解码、批量推理、语法约束生成、LoRA、多 GPU、自定义构建、基准脚本
|
||||
- **[quantization.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/quantization.md)** — 量化质量权衡、何时使用 Q4/Q5/Q6/IQ、模型大小缩放、imatrix
|
||||
- **[server.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/server.md)** — 直接从 Hub 启动服务器、OpenAI API 端点、Docker 部署、NGINX 负载均衡、监控
|
||||
- **[optimization.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/optimization.md)** — CPU 线程、BLAS、GPU 卸载启发式、批处理调优、基准测试
|
||||
- **[troubleshooting.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/llama-cpp/references/troubleshooting.md)** — 安装/转换/量化/推理/服务器问题、Apple Silicon、调试
|
||||
|
||||
## 资源
|
||||
|
||||
- **GitHub**:https://github.com/ggml-org/llama.cpp
|
||||
- **Hugging Face GGUF + llama.cpp 文档**:https://huggingface.co/docs/hub/gguf-llamacpp
|
||||
- **Hugging Face 本地应用文档**:https://huggingface.co/docs/hub/main/local-apps
|
||||
- **Hugging Face 本地 Agent 文档**:https://huggingface.co/docs/hub/agents-local
|
||||
- **local-app 页面示例**:https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF?local-app=llama.cpp
|
||||
- **tree API 示例**:https://huggingface.co/api/models/unsloth/Qwen3.6-35B-A3B-GGUF/tree/main?recursive=true
|
||||
- **llama.cpp 搜索示例**:https://huggingface.co/models?num_parameters=min:0,max:24B&apps=llama.cpp&sort=trending
|
||||
- **许可证**:MIT
|
||||
+386
@@ -0,0 +1,386 @@
|
||||
---
|
||||
title: "Serving Llms Vllm — vLLM:高吞吐量 LLM 服务、OpenAI API、量化"
|
||||
sidebar_label: "Serving Llms Vllm"
|
||||
description: "vLLM:高吞吐量 LLM 服务、OpenAI 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. */}
|
||||
|
||||
# Serving Llms Vllm
|
||||
|
||||
vLLM:高吞吐量 LLM 服务、OpenAI API、量化。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/inference/vllm` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖 | `vllm`, `torch`, `transformers` |
|
||||
| 平台 | linux, macos |
|
||||
| 标签 | `vLLM`, `Inference Serving`, `PagedAttention`, `Continuous Batching`, `High Throughput`, `Production`, `OpenAI API`, `Quantization`, `Tensor Parallelism` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# vLLM - 高性能 LLM 服务
|
||||
|
||||
## 适用场景
|
||||
|
||||
在部署生产级 LLM API、优化推理延迟/吞吐量,或在 GPU 显存有限的情况下服务模型时使用。支持 OpenAI 兼容端点、量化(GPTQ/AWQ/FP8)以及张量并行。
|
||||
|
||||
## 快速开始
|
||||
|
||||
vLLM 通过 PagedAttention(基于块的 KV 缓存)和 continuous batching(混合 prefill/decode 请求)实现比标准 transformers 高 24 倍的吞吐量。
|
||||
|
||||
**安装**:
|
||||
```bash
|
||||
pip install vllm
|
||||
```
|
||||
|
||||
**基础离线推理**:
|
||||
```python
|
||||
from vllm import LLM, SamplingParams
|
||||
|
||||
llm = LLM(model="meta-llama/Llama-3-8B-Instruct")
|
||||
sampling = SamplingParams(temperature=0.7, max_tokens=256)
|
||||
|
||||
outputs = llm.generate(["Explain quantum computing"], sampling)
|
||||
print(outputs[0].outputs[0].text)
|
||||
```
|
||||
|
||||
**OpenAI 兼容服务器**:
|
||||
```bash
|
||||
vllm serve meta-llama/Llama-3-8B-Instruct
|
||||
|
||||
# Query with OpenAI SDK
|
||||
python -c "
|
||||
from openai import OpenAI
|
||||
client = OpenAI(base_url='http://localhost:8000/v1', api_key='EMPTY')
|
||||
print(client.chat.completions.create(
|
||||
model='meta-llama/Llama-3-8B-Instruct',
|
||||
messages=[{'role': 'user', 'content': 'Hello!'}]
|
||||
).choices[0].message.content)
|
||||
"
|
||||
```
|
||||
|
||||
## 常见工作流
|
||||
|
||||
### 工作流 1:生产 API 部署
|
||||
|
||||
复制此清单并跟踪进度:
|
||||
|
||||
```
|
||||
Deployment Progress:
|
||||
- [ ] Step 1: Configure server settings
|
||||
- [ ] Step 2: Test with limited traffic
|
||||
- [ ] Step 3: Enable monitoring
|
||||
- [ ] Step 4: Deploy to production
|
||||
- [ ] Step 5: Verify performance metrics
|
||||
```
|
||||
|
||||
**步骤 1:配置服务器设置**
|
||||
|
||||
根据模型大小选择配置:
|
||||
|
||||
```bash
|
||||
# For 7B-13B models on single GPU
|
||||
vllm serve meta-llama/Llama-3-8B-Instruct \
|
||||
--gpu-memory-utilization 0.9 \
|
||||
--max-model-len 8192 \
|
||||
--port 8000
|
||||
|
||||
# For 30B-70B models with tensor parallelism
|
||||
vllm serve meta-llama/Llama-2-70b-hf \
|
||||
--tensor-parallel-size 4 \
|
||||
--gpu-memory-utilization 0.9 \
|
||||
--quantization awq \
|
||||
--port 8000
|
||||
|
||||
# For production with caching and metrics
|
||||
vllm serve meta-llama/Llama-3-8B-Instruct \
|
||||
--gpu-memory-utilization 0.9 \
|
||||
--enable-prefix-caching \
|
||||
--enable-metrics \
|
||||
--metrics-port 9090 \
|
||||
--port 8000 \
|
||||
--host 0.0.0.0
|
||||
```
|
||||
|
||||
**步骤 2:使用有限流量测试**
|
||||
|
||||
在生产前运行负载测试:
|
||||
|
||||
```bash
|
||||
# Install load testing tool
|
||||
pip install locust
|
||||
|
||||
# Create test_load.py with sample requests
|
||||
# Run: locust -f test_load.py --host http://localhost:8000
|
||||
```
|
||||
|
||||
验证 TTFT(首 token 时间)< 500ms,吞吐量 > 100 req/sec。
|
||||
|
||||
**步骤 3:启用监控**
|
||||
|
||||
vLLM 在端口 9090 上暴露 Prometheus 指标:
|
||||
|
||||
```bash
|
||||
curl http://localhost:9090/metrics | grep vllm
|
||||
```
|
||||
|
||||
需监控的关键指标:
|
||||
- `vllm:time_to_first_token_seconds` - 延迟
|
||||
- `vllm:num_requests_running` - 活跃请求数
|
||||
- `vllm:gpu_cache_usage_perc` - KV 缓存利用率
|
||||
|
||||
**步骤 4:部署到生产环境**
|
||||
|
||||
使用 Docker 实现一致性部署:
|
||||
|
||||
```bash
|
||||
# Run vLLM in Docker
|
||||
docker run --gpus all -p 8000:8000 \
|
||||
vllm/vllm-openai:latest \
|
||||
--model meta-llama/Llama-3-8B-Instruct \
|
||||
--gpu-memory-utilization 0.9 \
|
||||
--enable-prefix-caching
|
||||
```
|
||||
|
||||
**步骤 5:验证性能指标**
|
||||
|
||||
检查部署是否达到目标:
|
||||
- TTFT < 500ms(短 prompt 情况下)
|
||||
- 吞吐量 > 目标 req/sec
|
||||
- GPU 利用率 > 80%
|
||||
- 日志中无 OOM 错误
|
||||
|
||||
### 工作流 2:离线批量推理
|
||||
|
||||
用于处理大型数据集,无需服务器开销。
|
||||
|
||||
复制此清单:
|
||||
|
||||
```
|
||||
Batch Processing:
|
||||
- [ ] Step 1: Prepare input data
|
||||
- [ ] Step 2: Configure LLM engine
|
||||
- [ ] Step 3: Run batch inference
|
||||
- [ ] Step 4: Process results
|
||||
```
|
||||
|
||||
**步骤 1:准备输入数据**
|
||||
|
||||
```python
|
||||
# Load prompts from file
|
||||
prompts = []
|
||||
with open("prompts.txt") as f:
|
||||
prompts = [line.strip() for line in f]
|
||||
|
||||
print(f"Loaded {len(prompts)} prompts")
|
||||
```
|
||||
|
||||
**步骤 2:配置 LLM 引擎**
|
||||
|
||||
```python
|
||||
from vllm import LLM, SamplingParams
|
||||
|
||||
llm = LLM(
|
||||
model="meta-llama/Llama-3-8B-Instruct",
|
||||
tensor_parallel_size=2, # Use 2 GPUs
|
||||
gpu_memory_utilization=0.9,
|
||||
max_model_len=4096
|
||||
)
|
||||
|
||||
sampling = SamplingParams(
|
||||
temperature=0.7,
|
||||
top_p=0.95,
|
||||
max_tokens=512,
|
||||
stop=["</s>", "\n\n"]
|
||||
)
|
||||
```
|
||||
|
||||
**步骤 3:运行批量推理**
|
||||
|
||||
vLLM 自动对请求进行批处理以提升效率:
|
||||
|
||||
```python
|
||||
# Process all prompts in one call
|
||||
outputs = llm.generate(prompts, sampling)
|
||||
|
||||
# vLLM handles batching internally
|
||||
# No need to manually chunk prompts
|
||||
```
|
||||
|
||||
**步骤 4:处理结果**
|
||||
|
||||
```python
|
||||
# Extract generated text
|
||||
results = []
|
||||
for output in outputs:
|
||||
prompt = output.prompt
|
||||
generated = output.outputs[0].text
|
||||
results.append({
|
||||
"prompt": prompt,
|
||||
"generated": generated,
|
||||
"tokens": len(output.outputs[0].token_ids)
|
||||
})
|
||||
|
||||
# Save to file
|
||||
import json
|
||||
with open("results.jsonl", "w") as f:
|
||||
for result in results:
|
||||
f.write(json.dumps(result) + "\n")
|
||||
|
||||
print(f"Processed {len(results)} prompts")
|
||||
```
|
||||
|
||||
### 工作流 3:量化模型服务
|
||||
|
||||
在有限 GPU 显存中运行大型模型。
|
||||
|
||||
```
|
||||
Quantization Setup:
|
||||
- [ ] Step 1: Choose quantization method
|
||||
- [ ] Step 2: Find or create quantized model
|
||||
- [ ] Step 3: Launch with quantization flag
|
||||
- [ ] Step 4: Verify accuracy
|
||||
```
|
||||
|
||||
**步骤 1:选择量化方法**
|
||||
|
||||
- **AWQ**:最适合 70B 模型,精度损失极小
|
||||
- **GPTQ**:模型支持范围广,压缩效果好
|
||||
- **FP8**:在 H100 GPU 上速度最快
|
||||
|
||||
**步骤 2:查找或创建量化模型**
|
||||
|
||||
使用 HuggingFace 上的预量化模型:
|
||||
|
||||
```bash
|
||||
# Search for AWQ models
|
||||
# Example: TheBloke/Llama-2-70B-AWQ
|
||||
```
|
||||
|
||||
**步骤 3:使用量化标志启动**
|
||||
|
||||
```bash
|
||||
# Using pre-quantized model
|
||||
vllm serve TheBloke/Llama-2-70B-AWQ \
|
||||
--quantization awq \
|
||||
--tensor-parallel-size 1 \
|
||||
--gpu-memory-utilization 0.95
|
||||
|
||||
# Results: 70B model in ~40GB VRAM
|
||||
```
|
||||
|
||||
**步骤 4:验证精度**
|
||||
|
||||
测试输出是否符合预期质量:
|
||||
|
||||
```python
|
||||
# Compare quantized vs non-quantized responses
|
||||
# Verify task-specific performance unchanged
|
||||
```
|
||||
|
||||
## 与替代方案的对比
|
||||
|
||||
**使用 vLLM 的场景:**
|
||||
- 部署生产级 LLM API(100+ req/sec)
|
||||
- 提供 OpenAI 兼容端点
|
||||
- GPU 显存有限但需要运行大型模型
|
||||
- 多用户应用(聊天机器人、助手)
|
||||
- 需要低延迟与高吞吐量并存
|
||||
|
||||
**改用替代方案的场景:**
|
||||
- **llama.cpp**:CPU/边缘推理,单用户场景
|
||||
- **HuggingFace transformers**:研究、原型开发、一次性生成
|
||||
- **TensorRT-LLM**:仅限 NVIDIA,追求绝对最高性能
|
||||
- **Text-Generation-Inference**:已在 HuggingFace 生态系统中
|
||||
|
||||
## 常见问题
|
||||
|
||||
**问题:模型加载时内存不足**
|
||||
|
||||
减少内存使用:
|
||||
```bash
|
||||
vllm serve MODEL \
|
||||
--gpu-memory-utilization 0.7 \
|
||||
--max-model-len 4096
|
||||
```
|
||||
|
||||
或使用量化:
|
||||
```bash
|
||||
vllm serve MODEL --quantization awq
|
||||
```
|
||||
|
||||
**问题:首 token 速度慢(TTFT > 1 秒)**
|
||||
|
||||
对重复 prompt 启用前缀缓存:
|
||||
```bash
|
||||
vllm serve MODEL --enable-prefix-caching
|
||||
```
|
||||
|
||||
对长 prompt,启用分块 prefill:
|
||||
```bash
|
||||
vllm serve MODEL --enable-chunked-prefill
|
||||
```
|
||||
|
||||
**问题:模型未找到错误**
|
||||
|
||||
对自定义模型使用 `--trust-remote-code`:
|
||||
```bash
|
||||
vllm serve MODEL --trust-remote-code
|
||||
```
|
||||
|
||||
**问题:吞吐量低(<50 req/sec)**
|
||||
|
||||
增加并发序列数:
|
||||
```bash
|
||||
vllm serve MODEL --max-num-seqs 512
|
||||
```
|
||||
|
||||
使用 `nvidia-smi` 检查 GPU 利用率——应高于 80%。
|
||||
|
||||
**问题:推理速度低于预期**
|
||||
|
||||
验证张量并行使用的 GPU 数量为 2 的幂次:
|
||||
```bash
|
||||
vllm serve MODEL --tensor-parallel-size 4 # Not 3
|
||||
```
|
||||
|
||||
启用推测解码以加速生成:
|
||||
```bash
|
||||
vllm serve MODEL --speculative-model DRAFT_MODEL
|
||||
```
|
||||
|
||||
## 高级主题
|
||||
|
||||
**服务器部署模式**:参见 [references/server-deployment.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/vllm/references/server-deployment.md),了解 Docker、Kubernetes 和负载均衡配置。
|
||||
|
||||
**性能优化**:参见 [references/optimization.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/vllm/references/optimization.md),了解 PagedAttention 调优、continuous batching 详情及基准测试结果。
|
||||
|
||||
**量化指南**:参见 [references/quantization.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/vllm/references/quantization.md),了解 AWQ/GPTQ/FP8 配置、模型准备及精度对比。
|
||||
|
||||
**故障排查**:参见 [references/troubleshooting.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/inference/vllm/references/troubleshooting.md),了解详细错误信息、调试步骤及性能诊断。
|
||||
|
||||
## 硬件要求
|
||||
|
||||
- **小型模型(7B-13B)**:1x A10(24GB)或 A100(40GB)
|
||||
- **中型模型(30B-40B)**:2x A100(40GB),使用张量并行
|
||||
- **大型模型(70B+)**:4x A100(40GB)或 2x A100(80GB),使用 AWQ/GPTQ
|
||||
|
||||
支持平台:NVIDIA(主要)、AMD ROCm、Intel GPU、TPU
|
||||
|
||||
## 资源
|
||||
|
||||
- 官方文档:https://docs.vllm.ai
|
||||
- GitHub:https://github.com/vllm-project/vllm
|
||||
- 论文:"Efficient Memory Management for Large Language Model Serving with PagedAttention"(SOSP 2023)
|
||||
- 社区:https://discuss.vllm.ai
|
||||
+587
@@ -0,0 +1,587 @@
|
||||
---
|
||||
title: "Audiocraft 音频生成 — AudioCraft:MusicGen 文本转音乐,AudioGen 文本转声音"
|
||||
sidebar_label: "Audiocraft 音频生成"
|
||||
description: "AudioCraft:MusicGen 文本转音乐,AudioGen 文本转声音"
|
||||
---
|
||||
|
||||
{/* 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. */}
|
||||
|
||||
# Audiocraft 音频生成
|
||||
|
||||
AudioCraft:MusicGen 文本转音乐,AudioGen 文本转声音。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/models/audiocraft` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖 | `audiocraft`, `torch>=2.0.0`, `transformers>=4.30.0` |
|
||||
| 平台 | linux, macos |
|
||||
| 标签 | `Multimodal`, `Audio Generation`, `Text-to-Music`, `Text-to-Audio`, `MusicGen` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# AudioCraft:音频生成
|
||||
|
||||
使用 Meta 的 AudioCraft 进行文本转音乐和文本转音频生成的完整指南,涵盖 MusicGen、AudioGen 和 EnCodec。
|
||||
|
||||
## 何时使用 AudioCraft
|
||||
|
||||
**在以下情况下使用 AudioCraft:**
|
||||
- 需要从文本描述生成音乐
|
||||
- 创建音效和环境音频
|
||||
- 构建音乐生成应用
|
||||
- 需要旋律条件化的音乐生成
|
||||
- 需要立体声音频输出
|
||||
- 需要可控的风格迁移音乐生成
|
||||
|
||||
**核心功能:**
|
||||
- **MusicGen**:支持旋律条件化的文本转音乐生成
|
||||
- **AudioGen**:文本转音效生成
|
||||
- **EnCodec**:高保真神经音频编解码器
|
||||
- **多种模型规格**:从 Small(300M)到 Large(3.3B)
|
||||
- **立体声支持**:完整立体声音频生成
|
||||
- **风格条件化**:MusicGen-Style 支持基于参考的生成
|
||||
|
||||
**以下情况请使用替代方案:**
|
||||
- **Stable Audio**:用于较长的商业音乐生成
|
||||
- **Bark**:用于带音乐/音效的文本转语音
|
||||
- **Riffusion**:用于基于频谱图的音乐生成
|
||||
- **OpenAI Jukebox**:用于带歌词的原始音频生成
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
# 从 PyPI 安装
|
||||
pip install audiocraft
|
||||
|
||||
# 从 GitHub 安装(最新版)
|
||||
pip install git+https://github.com/facebookresearch/audiocraft.git
|
||||
|
||||
# 或使用 HuggingFace Transformers
|
||||
pip install transformers torch torchaudio
|
||||
```
|
||||
|
||||
### 基础文本转音乐(AudioCraft)
|
||||
|
||||
```python
|
||||
import torchaudio
|
||||
from audiocraft.models import MusicGen
|
||||
|
||||
# 加载模型
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-small')
|
||||
|
||||
# 设置生成参数
|
||||
model.set_generation_params(
|
||||
duration=8, # 秒
|
||||
top_k=250,
|
||||
temperature=1.0
|
||||
)
|
||||
|
||||
# 从文本生成
|
||||
descriptions = ["happy upbeat electronic dance music with synths"]
|
||||
wav = model.generate(descriptions)
|
||||
|
||||
# 保存音频
|
||||
torchaudio.save("output.wav", wav[0].cpu(), sample_rate=32000)
|
||||
```
|
||||
|
||||
### 使用 HuggingFace Transformers
|
||||
|
||||
```python
|
||||
from transformers import AutoProcessor, MusicgenForConditionalGeneration
|
||||
import scipy
|
||||
|
||||
# 加载模型和处理器
|
||||
processor = AutoProcessor.from_pretrained("facebook/musicgen-small")
|
||||
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-small")
|
||||
model.to("cuda")
|
||||
|
||||
# 生成音乐
|
||||
inputs = processor(
|
||||
text=["80s pop track with bassy drums and synth"],
|
||||
padding=True,
|
||||
return_tensors="pt"
|
||||
).to("cuda")
|
||||
|
||||
audio_values = model.generate(
|
||||
**inputs,
|
||||
do_sample=True,
|
||||
guidance_scale=3,
|
||||
max_new_tokens=256
|
||||
)
|
||||
|
||||
# 保存
|
||||
sampling_rate = model.config.audio_encoder.sampling_rate
|
||||
scipy.io.wavfile.write("output.wav", rate=sampling_rate, data=audio_values[0, 0].cpu().numpy())
|
||||
```
|
||||
|
||||
### 使用 AudioGen 进行文本转声音
|
||||
|
||||
```python
|
||||
from audiocraft.models import AudioGen
|
||||
|
||||
# 加载 AudioGen
|
||||
model = AudioGen.get_pretrained('facebook/audiogen-medium')
|
||||
|
||||
model.set_generation_params(duration=5)
|
||||
|
||||
# 生成音效
|
||||
descriptions = ["dog barking in a park with birds chirping"]
|
||||
wav = model.generate(descriptions)
|
||||
|
||||
torchaudio.save("sound.wav", wav[0].cpu(), sample_rate=16000)
|
||||
```
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 架构概览
|
||||
|
||||
<!-- ascii-guard-ignore -->
|
||||
```
|
||||
AudioCraft Architecture:
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Text Encoder (T5) │
|
||||
│ │ │
|
||||
│ Text Embeddings │
|
||||
└────────────────────────┬─────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────────▼─────────────────────────────────────┐
|
||||
│ Transformer Decoder (LM) │
|
||||
│ Auto-regressively generates audio tokens │
|
||||
│ Using efficient token interleaving patterns │
|
||||
└────────────────────────┬─────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────────▼─────────────────────────────────────┐
|
||||
│ EnCodec Audio Decoder │
|
||||
│ Converts tokens back to audio waveform │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
<!-- ascii-guard-ignore-end -->
|
||||
|
||||
### 模型变体
|
||||
|
||||
| 模型 | 规模 | 描述 | 适用场景 |
|
||||
|-------|------|-------------|----------|
|
||||
| `musicgen-small` | 300M | 文本转音乐 | 快速生成 |
|
||||
| `musicgen-medium` | 1.5B | 文本转音乐 | 均衡选择 |
|
||||
| `musicgen-large` | 3.3B | 文本转音乐 | 最佳质量 |
|
||||
| `musicgen-melody` | 1.5B | 文本 + 旋律 | 旋律条件化 |
|
||||
| `musicgen-melody-large` | 3.3B | 文本 + 旋律 | 最佳旋律效果 |
|
||||
| `musicgen-stereo-*` | 不定 | 立体声输出 | 立体声生成 |
|
||||
| `musicgen-style` | 1.5B | 风格迁移 | 基于参考的生成 |
|
||||
| `audiogen-medium` | 1.5B | 文本转声音 | 音效生成 |
|
||||
|
||||
### 生成参数
|
||||
|
||||
| 参数 | 默认值 | 描述 |
|
||||
|-----------|---------|-------------|
|
||||
| `duration` | 8.0 | 时长(秒),范围 1-120 |
|
||||
| `top_k` | 250 | Top-k 采样 |
|
||||
| `top_p` | 0.0 | Nucleus 采样(0 = 禁用) |
|
||||
| `temperature` | 1.0 | 采样温度 |
|
||||
| `cfg_coef` | 3.0 | 无分类器引导系数 |
|
||||
|
||||
## MusicGen 用法
|
||||
|
||||
### 文本转音乐生成
|
||||
|
||||
```python
|
||||
from audiocraft.models import MusicGen
|
||||
import torchaudio
|
||||
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-medium')
|
||||
|
||||
# 配置生成参数
|
||||
model.set_generation_params(
|
||||
duration=30, # 最长 30 秒
|
||||
top_k=250, # 采样多样性
|
||||
top_p=0.0, # 0 = 仅使用 top_k
|
||||
temperature=1.0, # 创意度(越高越多样)
|
||||
cfg_coef=3.0 # 文本遵循度(越高越严格)
|
||||
)
|
||||
|
||||
# 生成多个样本
|
||||
descriptions = [
|
||||
"epic orchestral soundtrack with strings and brass",
|
||||
"chill lo-fi hip hop beat with jazzy piano",
|
||||
"energetic rock song with electric guitar"
|
||||
]
|
||||
|
||||
# 生成(返回 [batch, channels, samples])
|
||||
wav = model.generate(descriptions)
|
||||
|
||||
# 逐个保存
|
||||
for i, audio in enumerate(wav):
|
||||
torchaudio.save(f"music_{i}.wav", audio.cpu(), sample_rate=32000)
|
||||
```
|
||||
|
||||
### 旋律条件化生成
|
||||
|
||||
```python
|
||||
from audiocraft.models import MusicGen
|
||||
import torchaudio
|
||||
|
||||
# 加载旋律模型
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-melody')
|
||||
model.set_generation_params(duration=30)
|
||||
|
||||
# 加载旋律音频
|
||||
melody, sr = torchaudio.load("melody.wav")
|
||||
|
||||
# 使用旋律条件化生成
|
||||
descriptions = ["acoustic guitar folk song"]
|
||||
wav = model.generate_with_chroma(descriptions, melody, sr)
|
||||
|
||||
torchaudio.save("melody_conditioned.wav", wav[0].cpu(), sample_rate=32000)
|
||||
```
|
||||
|
||||
### 立体声生成
|
||||
|
||||
```python
|
||||
from audiocraft.models import MusicGen
|
||||
|
||||
# 加载立体声模型
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-stereo-medium')
|
||||
model.set_generation_params(duration=15)
|
||||
|
||||
descriptions = ["ambient electronic music with wide stereo panning"]
|
||||
wav = model.generate(descriptions)
|
||||
|
||||
# wav 形状:立体声为 [batch, 2, samples]
|
||||
print(f"Stereo shape: {wav.shape}") # [1, 2, 480000]
|
||||
torchaudio.save("stereo.wav", wav[0].cpu(), sample_rate=32000)
|
||||
```
|
||||
|
||||
### 音频续写
|
||||
|
||||
```python
|
||||
from transformers import AutoProcessor, MusicgenForConditionalGeneration
|
||||
|
||||
processor = AutoProcessor.from_pretrained("facebook/musicgen-medium")
|
||||
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-medium")
|
||||
|
||||
# 加载待续写的音频
|
||||
import torchaudio
|
||||
audio, sr = torchaudio.load("intro.wav")
|
||||
|
||||
# 同时处理文本和音频
|
||||
inputs = processor(
|
||||
audio=audio.squeeze().numpy(),
|
||||
sampling_rate=sr,
|
||||
text=["continue with a epic chorus"],
|
||||
padding=True,
|
||||
return_tensors="pt"
|
||||
)
|
||||
|
||||
# 生成续写内容
|
||||
audio_values = model.generate(**inputs, do_sample=True, guidance_scale=3, max_new_tokens=512)
|
||||
```
|
||||
|
||||
## MusicGen-Style 用法
|
||||
|
||||
### 风格条件化生成
|
||||
|
||||
```python
|
||||
from audiocraft.models import MusicGen
|
||||
|
||||
# 加载风格模型
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-style')
|
||||
|
||||
# 配置带风格的生成参数
|
||||
model.set_generation_params(
|
||||
duration=30,
|
||||
cfg_coef=3.0,
|
||||
cfg_coef_beta=5.0 # 风格影响强度
|
||||
)
|
||||
|
||||
# 配置风格条件器参数
|
||||
model.set_style_conditioner_params(
|
||||
eval_q=3, # RVQ 量化器数量(1-6)
|
||||
excerpt_length=3.0 # 风格片段长度
|
||||
)
|
||||
|
||||
# 加载风格参考音频
|
||||
style_audio, sr = torchaudio.load("reference_style.wav")
|
||||
|
||||
# 使用文本 + 风格生成
|
||||
descriptions = ["upbeat dance track"]
|
||||
wav = model.generate_with_style(descriptions, style_audio, sr)
|
||||
```
|
||||
|
||||
### 仅风格生成(无文本)
|
||||
|
||||
```python
|
||||
# 不使用文本 prompt,仅匹配风格生成
|
||||
model.set_generation_params(
|
||||
duration=30,
|
||||
cfg_coef=3.0,
|
||||
cfg_coef_beta=None # 禁用双 CFG 以支持纯风格模式
|
||||
)
|
||||
|
||||
wav = model.generate_with_style([None], style_audio, sr)
|
||||
```
|
||||
|
||||
## AudioGen 用法
|
||||
|
||||
### 音效生成
|
||||
|
||||
```python
|
||||
from audiocraft.models import AudioGen
|
||||
import torchaudio
|
||||
|
||||
model = AudioGen.get_pretrained('facebook/audiogen-medium')
|
||||
model.set_generation_params(duration=10)
|
||||
|
||||
# 生成各类声音
|
||||
descriptions = [
|
||||
"thunderstorm with heavy rain and lightning",
|
||||
"busy city traffic with car horns",
|
||||
"ocean waves crashing on rocks",
|
||||
"crackling campfire in forest"
|
||||
]
|
||||
|
||||
wav = model.generate(descriptions)
|
||||
|
||||
for i, audio in enumerate(wav):
|
||||
torchaudio.save(f"sound_{i}.wav", audio.cpu(), sample_rate=16000)
|
||||
```
|
||||
|
||||
## EnCodec 用法
|
||||
|
||||
### 音频压缩
|
||||
|
||||
```python
|
||||
from audiocraft.models import CompressionModel
|
||||
import torch
|
||||
import torchaudio
|
||||
|
||||
# 加载 EnCodec
|
||||
model = CompressionModel.get_pretrained('facebook/encodec_32khz')
|
||||
|
||||
# 加载音频
|
||||
wav, sr = torchaudio.load("audio.wav")
|
||||
|
||||
# 确保采样率正确
|
||||
if sr != 32000:
|
||||
resampler = torchaudio.transforms.Resample(sr, 32000)
|
||||
wav = resampler(wav)
|
||||
|
||||
# 编码为 token
|
||||
with torch.no_grad():
|
||||
encoded = model.encode(wav.unsqueeze(0))
|
||||
codes = encoded[0] # 音频编码
|
||||
|
||||
# 解码回音频
|
||||
with torch.no_grad():
|
||||
decoded = model.decode(codes)
|
||||
|
||||
torchaudio.save("reconstructed.wav", decoded[0].cpu(), sample_rate=32000)
|
||||
```
|
||||
|
||||
## 常见工作流
|
||||
|
||||
### 工作流 1:音乐生成流水线
|
||||
|
||||
```python
|
||||
import torch
|
||||
import torchaudio
|
||||
from audiocraft.models import MusicGen
|
||||
|
||||
class MusicGenerator:
|
||||
def __init__(self, model_name="facebook/musicgen-medium"):
|
||||
self.model = MusicGen.get_pretrained(model_name)
|
||||
self.sample_rate = 32000
|
||||
|
||||
def generate(self, prompt, duration=30, temperature=1.0, cfg=3.0):
|
||||
self.model.set_generation_params(
|
||||
duration=duration,
|
||||
top_k=250,
|
||||
temperature=temperature,
|
||||
cfg_coef=cfg
|
||||
)
|
||||
|
||||
with torch.no_grad():
|
||||
wav = self.model.generate([prompt])
|
||||
|
||||
return wav[0].cpu()
|
||||
|
||||
def generate_batch(self, prompts, duration=30):
|
||||
self.model.set_generation_params(duration=duration)
|
||||
|
||||
with torch.no_grad():
|
||||
wav = self.model.generate(prompts)
|
||||
|
||||
return wav.cpu()
|
||||
|
||||
def save(self, audio, path):
|
||||
torchaudio.save(path, audio, sample_rate=self.sample_rate)
|
||||
|
||||
# 使用示例
|
||||
generator = MusicGenerator()
|
||||
audio = generator.generate(
|
||||
"epic cinematic orchestral music",
|
||||
duration=30,
|
||||
temperature=1.0
|
||||
)
|
||||
generator.save(audio, "epic_music.wav")
|
||||
```
|
||||
|
||||
### 工作流 2:音效批量处理
|
||||
|
||||
```python
|
||||
import json
|
||||
from pathlib import Path
|
||||
from audiocraft.models import AudioGen
|
||||
import torchaudio
|
||||
|
||||
def batch_generate_sounds(sound_specs, output_dir):
|
||||
"""
|
||||
根据规格批量生成声音。
|
||||
|
||||
Args:
|
||||
sound_specs: list of {"name": str, "description": str, "duration": float}
|
||||
output_dir: output directory path
|
||||
"""
|
||||
model = AudioGen.get_pretrained('facebook/audiogen-medium')
|
||||
output_dir = Path(output_dir)
|
||||
output_dir.mkdir(exist_ok=True)
|
||||
|
||||
results = []
|
||||
|
||||
for spec in sound_specs:
|
||||
model.set_generation_params(duration=spec.get("duration", 5))
|
||||
|
||||
wav = model.generate([spec["description"]])
|
||||
|
||||
output_path = output_dir / f"{spec['name']}.wav"
|
||||
torchaudio.save(str(output_path), wav[0].cpu(), sample_rate=16000)
|
||||
|
||||
results.append({
|
||||
"name": spec["name"],
|
||||
"path": str(output_path),
|
||||
"description": spec["description"]
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
# 使用示例
|
||||
sounds = [
|
||||
{"name": "explosion", "description": "massive explosion with debris", "duration": 3},
|
||||
{"name": "footsteps", "description": "footsteps on wooden floor", "duration": 5},
|
||||
{"name": "door", "description": "wooden door creaking and closing", "duration": 2}
|
||||
]
|
||||
|
||||
results = batch_generate_sounds(sounds, "sound_effects/")
|
||||
```
|
||||
|
||||
### 工作流 3:Gradio 演示
|
||||
|
||||
```python
|
||||
import gradio as gr
|
||||
import torch
|
||||
import torchaudio
|
||||
from audiocraft.models import MusicGen
|
||||
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-small')
|
||||
|
||||
def generate_music(prompt, duration, temperature, cfg_coef):
|
||||
model.set_generation_params(
|
||||
duration=duration,
|
||||
temperature=temperature,
|
||||
cfg_coef=cfg_coef
|
||||
)
|
||||
|
||||
with torch.no_grad():
|
||||
wav = model.generate([prompt])
|
||||
|
||||
# 保存到临时文件
|
||||
path = "temp_output.wav"
|
||||
torchaudio.save(path, wav[0].cpu(), sample_rate=32000)
|
||||
return path
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=generate_music,
|
||||
inputs=[
|
||||
gr.Textbox(label="Music Description", placeholder="upbeat electronic dance music"),
|
||||
gr.Slider(1, 30, value=8, label="Duration (seconds)"),
|
||||
gr.Slider(0.5, 2.0, value=1.0, label="Temperature"),
|
||||
gr.Slider(1.0, 10.0, value=3.0, label="CFG Coefficient")
|
||||
],
|
||||
outputs=gr.Audio(label="Generated Music"),
|
||||
title="MusicGen Demo"
|
||||
)
|
||||
|
||||
demo.launch()
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 内存优化
|
||||
|
||||
```python
|
||||
# 使用较小的模型
|
||||
model = MusicGen.get_pretrained('facebook/musicgen-small')
|
||||
|
||||
# 每次生成后清理缓存
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
# 生成较短的时长
|
||||
model.set_generation_params(duration=10) # 替代 30 秒
|
||||
|
||||
# 使用半精度
|
||||
model = model.half()
|
||||
```
|
||||
|
||||
### 批处理效率
|
||||
|
||||
```python
|
||||
# 一次处理多个 prompt(更高效)
|
||||
descriptions = ["prompt1", "prompt2", "prompt3", "prompt4"]
|
||||
wav = model.generate(descriptions) # 单次批处理
|
||||
|
||||
# 而非
|
||||
for desc in descriptions:
|
||||
wav = model.generate([desc]) # 多次批处理(较慢)
|
||||
```
|
||||
|
||||
### GPU 显存需求
|
||||
|
||||
| 模型 | FP32 显存 | FP16 显存 |
|
||||
|-------|-----------|-----------|
|
||||
| musicgen-small | ~4GB | ~2GB |
|
||||
| musicgen-medium | ~8GB | ~4GB |
|
||||
| musicgen-large | ~16GB | ~8GB |
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 问题 | 解决方案 |
|
||||
|-------|----------|
|
||||
| CUDA 显存不足 | 使用较小模型,缩短时长 |
|
||||
| 质量较差 | 提高 cfg_coef,优化 prompt |
|
||||
| 生成时长过短 | 检查最大时长设置 |
|
||||
| 音频有杂音 | 尝试不同的 temperature |
|
||||
| 立体声不生效 | 使用立体声模型变体 |
|
||||
|
||||
## 参考资料
|
||||
|
||||
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/audiocraft/references/advanced-usage.md)** - 训练、微调、部署
|
||||
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/audiocraft/references/troubleshooting.md)** - 常见问题与解决方案
|
||||
|
||||
## 资源
|
||||
|
||||
- **GitHub**:https://github.com/facebookresearch/audiocraft
|
||||
- **论文(MusicGen)**:https://arxiv.org/abs/2306.05284
|
||||
- **论文(AudioGen)**:https://arxiv.org/abs/2209.15352
|
||||
- **HuggingFace**:https://huggingface.co/facebook/musicgen-small
|
||||
- **演示**:https://huggingface.co/spaces/facebook/MusicGen
|
||||
+525
@@ -0,0 +1,525 @@
|
||||
---
|
||||
title: "Segment Anything Model — SAM:通过点、框、掩码实现零样本图像分割"
|
||||
sidebar_label: "Segment Anything Model"
|
||||
description: "SAM:通过点、框、掩码实现零样本图像分割"
|
||||
---
|
||||
|
||||
{/* 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. */}
|
||||
|
||||
# Segment Anything Model
|
||||
|
||||
SAM:通过点、框、掩码实现零样本图像分割。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 内置(默认安装) |
|
||||
| 路径 | `skills/mlops/models/segment-anything` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | Orchestra Research |
|
||||
| 许可证 | MIT |
|
||||
| 依赖项 | `segment-anything`, `transformers>=4.30.0`, `torch>=1.7.0` |
|
||||
| 平台 | linux, macos, windows |
|
||||
| 标签 | `Multimodal`, `Image Segmentation`, `Computer Vision`, `SAM`, `Zero-Shot` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
|
||||
:::
|
||||
|
||||
# Segment Anything Model (SAM)
|
||||
|
||||
Meta AI Segment Anything Model 零样本图像分割综合使用指南。
|
||||
|
||||
## 何时使用 SAM
|
||||
|
||||
**在以下情况使用 SAM:**
|
||||
- 需要在无需任务特定训练的情况下分割图像中的任意对象
|
||||
- 构建支持点/框 prompt(提示词)的交互式标注工具
|
||||
- 为其他视觉模型生成训练数据
|
||||
- 需要零样本迁移到新图像域
|
||||
- 构建目标检测/分割流水线
|
||||
- 处理医学、卫星或特定领域图像
|
||||
|
||||
**核心特性:**
|
||||
- **零样本分割**:无需微调即可适用于任意图像域
|
||||
- **灵活的 prompt**:支持点、边界框或先前掩码
|
||||
- **自动分割**:自动生成所有对象掩码
|
||||
- **高质量**:在来自 1100 万张图像的 11 亿个掩码上训练
|
||||
- **多种模型规格**:ViT-B(最快)、ViT-L、ViT-H(最精确)
|
||||
- **ONNX 导出**:可在浏览器和边缘设备上部署
|
||||
|
||||
**以下情况请使用替代方案:**
|
||||
- **YOLO/Detectron2**:用于带类别的实时目标检测
|
||||
- **Mask2Former**:用于带类别的语义/全景分割
|
||||
- **GroundingDINO + SAM**:用于文本 prompt 驱动的分割
|
||||
- **SAM 2**:用于视频分割任务
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
# 从 GitHub 安装
|
||||
pip install git+https://github.com/facebookresearch/segment-anything.git
|
||||
|
||||
# 可选依赖
|
||||
pip install opencv-python pycocotools matplotlib
|
||||
|
||||
# 或使用 HuggingFace transformers
|
||||
pip install transformers
|
||||
```
|
||||
|
||||
### 下载检查点
|
||||
|
||||
```bash
|
||||
# ViT-H(最大,最精确)- 2.4GB
|
||||
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth
|
||||
|
||||
# ViT-L(中等)- 1.2GB
|
||||
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth
|
||||
|
||||
# ViT-B(最小,最快)- 375MB
|
||||
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth
|
||||
```
|
||||
|
||||
### 使用 SamPredictor 的基本用法
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
from segment_anything import sam_model_registry, SamPredictor
|
||||
|
||||
# 加载模型
|
||||
sam = sam_model_registry["vit_h"](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/segment-anything/checkpoint="sam_vit_h_4b8939.pth")
|
||||
sam.to(device="cuda")
|
||||
|
||||
# 创建预测器
|
||||
predictor = SamPredictor(sam)
|
||||
|
||||
# 设置图像(一次性计算嵌入)
|
||||
image = cv2.imread("image.jpg")
|
||||
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
predictor.set_image(image)
|
||||
|
||||
# 使用点 prompt 进行预测
|
||||
input_point = np.array([[500, 375]]) # (x, y) 坐标
|
||||
input_label = np.array([1]) # 1 = 前景,0 = 背景
|
||||
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=input_point,
|
||||
point_labels=input_label,
|
||||
multimask_output=True # 返回 3 个掩码选项
|
||||
)
|
||||
|
||||
# 选择最佳掩码
|
||||
best_mask = masks[np.argmax(scores)]
|
||||
```
|
||||
|
||||
### HuggingFace Transformers
|
||||
|
||||
```python
|
||||
import torch
|
||||
from PIL import Image
|
||||
from transformers import SamModel, SamProcessor
|
||||
|
||||
# 加载模型和处理器
|
||||
model = SamModel.from_pretrained("facebook/sam-vit-huge")
|
||||
processor = SamProcessor.from_pretrained("facebook/sam-vit-huge")
|
||||
model.to("cuda")
|
||||
|
||||
# 使用点 prompt 处理图像
|
||||
image = Image.open("image.jpg")
|
||||
input_points = [[[450, 600]]] # 批量点
|
||||
|
||||
inputs = processor(image, input_points=input_points, return_tensors="pt")
|
||||
inputs = {k: v.to("cuda") for k, v in inputs.items()}
|
||||
|
||||
# 生成掩码
|
||||
with torch.no_grad():
|
||||
outputs = model(**inputs)
|
||||
|
||||
# 将掩码后处理还原至原始尺寸
|
||||
masks = processor.image_processor.post_process_masks(
|
||||
outputs.pred_masks.cpu(),
|
||||
inputs["original_sizes"].cpu(),
|
||||
inputs["reshaped_input_sizes"].cpu()
|
||||
)
|
||||
```
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 模型架构
|
||||
|
||||
<!-- ascii-guard-ignore -->
|
||||
<!-- ascii-guard-ignore -->
|
||||
```
|
||||
SAM Architecture:
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Image Encoder │────▶│ Prompt Encoder │────▶│ Mask Decoder │
|
||||
│ (ViT) │ │ (Points/Boxes) │ │ (Transformer) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│ │ │
|
||||
Image Embeddings Prompt Embeddings Masks + IoU
|
||||
(computed once) (per prompt) predictions
|
||||
```
|
||||
<!-- ascii-guard-ignore-end -->
|
||||
<!-- ascii-guard-ignore-end -->
|
||||
|
||||
### 模型变体
|
||||
|
||||
| 模型 | 检查点 | 大小 | 速度 | 精度 |
|
||||
|-------|------------|------|-------|----------|
|
||||
| ViT-H | `vit_h` | 2.4 GB | 最慢 | 最佳 |
|
||||
| ViT-L | `vit_l` | 1.2 GB | 中等 | 良好 |
|
||||
| ViT-B | `vit_b` | 375 MB | 最快 | 良好 |
|
||||
|
||||
### Prompt 类型
|
||||
|
||||
| Prompt | 描述 | 使用场景 |
|
||||
|--------|-------------|----------|
|
||||
| 点(前景) | 点击对象 | 单对象选择 |
|
||||
| 点(背景) | 点击对象外部 | 排除区域 |
|
||||
| 边界框 | 对象周围的矩形 | 较大对象 |
|
||||
| 先前掩码 | 低分辨率掩码输入 | 迭代精化 |
|
||||
|
||||
## 交互式分割
|
||||
|
||||
### 点 prompt
|
||||
|
||||
```python
|
||||
# 单个前景点
|
||||
input_point = np.array([[500, 375]])
|
||||
input_label = np.array([1])
|
||||
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=input_point,
|
||||
point_labels=input_label,
|
||||
multimask_output=True
|
||||
)
|
||||
|
||||
# 多个点(前景 + 背景)
|
||||
input_points = np.array([[500, 375], [600, 400], [450, 300]])
|
||||
input_labels = np.array([1, 1, 0]) # 2 个前景,1 个背景
|
||||
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=input_points,
|
||||
point_labels=input_labels,
|
||||
multimask_output=False # prompt 明确时使用单掩码
|
||||
)
|
||||
```
|
||||
|
||||
### 框 prompt
|
||||
|
||||
```python
|
||||
# 边界框 [x1, y1, x2, y2]
|
||||
input_box = np.array([425, 600, 700, 875])
|
||||
|
||||
masks, scores, logits = predictor.predict(
|
||||
box=input_box,
|
||||
multimask_output=False
|
||||
)
|
||||
```
|
||||
|
||||
### 组合 prompt
|
||||
|
||||
```python
|
||||
# 框 + 点,实现精确控制
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=np.array([[500, 375]]),
|
||||
point_labels=np.array([1]),
|
||||
box=np.array([400, 300, 700, 600]),
|
||||
multimask_output=False
|
||||
)
|
||||
```
|
||||
|
||||
### 迭代精化
|
||||
|
||||
```python
|
||||
# 初始预测
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=np.array([[500, 375]]),
|
||||
point_labels=np.array([1]),
|
||||
multimask_output=True
|
||||
)
|
||||
|
||||
# 使用先前掩码添加额外点进行精化
|
||||
masks, scores, logits = predictor.predict(
|
||||
point_coords=np.array([[500, 375], [550, 400]]),
|
||||
point_labels=np.array([1, 0]), # 添加背景点
|
||||
mask_input=logits[np.argmax(scores)][None, :, :], # 使用最佳掩码
|
||||
multimask_output=False
|
||||
)
|
||||
```
|
||||
|
||||
## 自动掩码生成
|
||||
|
||||
### 基本自动分割
|
||||
|
||||
```python
|
||||
from segment_anything import SamAutomaticMaskGenerator
|
||||
|
||||
# 创建生成器
|
||||
mask_generator = SamAutomaticMaskGenerator(sam)
|
||||
|
||||
# 生成所有掩码
|
||||
masks = mask_generator.generate(image)
|
||||
|
||||
# 每个掩码包含:
|
||||
# - segmentation: 二值掩码
|
||||
# - bbox: [x, y, w, h]
|
||||
# - area: 像素数量
|
||||
# - predicted_iou: 质量分数
|
||||
# - stability_score: 鲁棒性分数
|
||||
# - point_coords: 生成点
|
||||
```
|
||||
|
||||
### 自定义生成
|
||||
|
||||
```python
|
||||
mask_generator = SamAutomaticMaskGenerator(
|
||||
model=sam,
|
||||
points_per_side=32, # 网格密度(越大 = 掩码越多)
|
||||
pred_iou_thresh=0.88, # 质量阈值
|
||||
stability_score_thresh=0.95, # 稳定性阈值
|
||||
crop_n_layers=1, # 多尺度裁剪
|
||||
crop_n_points_downscale_factor=2,
|
||||
min_mask_region_area=100, # 移除微小掩码
|
||||
)
|
||||
|
||||
masks = mask_generator.generate(image)
|
||||
```
|
||||
|
||||
### 过滤掩码
|
||||
|
||||
```python
|
||||
# 按面积排序(最大优先)
|
||||
masks = sorted(masks, key=lambda x: x['area'], reverse=True)
|
||||
|
||||
# 按预测 IoU 过滤
|
||||
high_quality = [m for m in masks if m['predicted_iou'] > 0.9]
|
||||
|
||||
# 按稳定性分数过滤
|
||||
stable_masks = [m for m in masks if m['stability_score'] > 0.95]
|
||||
```
|
||||
|
||||
## 批量推理
|
||||
|
||||
### 多张图像
|
||||
|
||||
```python
|
||||
# 高效处理多张图像
|
||||
images = [cv2.imread(f"image_{i}.jpg") for i in range(10)]
|
||||
|
||||
all_masks = []
|
||||
for image in images:
|
||||
predictor.set_image(image)
|
||||
masks, _, _ = predictor.predict(
|
||||
point_coords=np.array([[500, 375]]),
|
||||
point_labels=np.array([1]),
|
||||
multimask_output=True
|
||||
)
|
||||
all_masks.append(masks)
|
||||
```
|
||||
|
||||
### 每张图像多个 prompt
|
||||
|
||||
```python
|
||||
# 高效处理多个 prompt(单次图像编码)
|
||||
predictor.set_image(image)
|
||||
|
||||
# 批量点 prompt
|
||||
points = [
|
||||
np.array([[100, 100]]),
|
||||
np.array([[200, 200]]),
|
||||
np.array([[300, 300]])
|
||||
]
|
||||
|
||||
all_masks = []
|
||||
for point in points:
|
||||
masks, scores, _ = predictor.predict(
|
||||
point_coords=point,
|
||||
point_labels=np.array([1]),
|
||||
multimask_output=True
|
||||
)
|
||||
all_masks.append(masks[np.argmax(scores)])
|
||||
```
|
||||
|
||||
## ONNX 部署
|
||||
|
||||
### 导出模型
|
||||
|
||||
```bash
|
||||
python scripts/export_onnx_model.py \
|
||||
--checkpoint sam_vit_h_4b8939.pth \
|
||||
--model-type vit_h \
|
||||
--output sam_onnx.onnx \
|
||||
--return-single-mask
|
||||
```
|
||||
|
||||
### 使用 ONNX 模型
|
||||
|
||||
```python
|
||||
import onnxruntime
|
||||
|
||||
# 加载 ONNX 模型
|
||||
ort_session = onnxruntime.InferenceSession("sam_onnx.onnx")
|
||||
|
||||
# 运行推理(图像嵌入单独计算)
|
||||
masks = ort_session.run(
|
||||
None,
|
||||
{
|
||||
"image_embeddings": image_embeddings,
|
||||
"point_coords": point_coords,
|
||||
"point_labels": point_labels,
|
||||
"mask_input": np.zeros((1, 1, 256, 256), dtype=np.float32),
|
||||
"has_mask_input": np.array([0], dtype=np.float32),
|
||||
"orig_im_size": np.array([h, w], dtype=np.float32)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 常见工作流
|
||||
|
||||
### 工作流 1:标注工具
|
||||
|
||||
```python
|
||||
import cv2
|
||||
|
||||
# 加载模型
|
||||
predictor = SamPredictor(sam)
|
||||
predictor.set_image(image)
|
||||
|
||||
def on_click(event, x, y, flags, param):
|
||||
if event == cv2.EVENT_LBUTTONDOWN:
|
||||
# 前景点
|
||||
masks, scores, _ = predictor.predict(
|
||||
point_coords=np.array([[x, y]]),
|
||||
point_labels=np.array([1]),
|
||||
multimask_output=True
|
||||
)
|
||||
# 显示最佳掩码
|
||||
display_mask(masks[np.argmax(scores)])
|
||||
```
|
||||
|
||||
### 工作流 2:对象提取
|
||||
|
||||
```python
|
||||
def extract_object(image, point):
|
||||
"""提取指定点处的对象并设置透明背景。"""
|
||||
predictor.set_image(image)
|
||||
|
||||
masks, scores, _ = predictor.predict(
|
||||
point_coords=np.array([point]),
|
||||
point_labels=np.array([1]),
|
||||
multimask_output=True
|
||||
)
|
||||
|
||||
best_mask = masks[np.argmax(scores)]
|
||||
|
||||
# 创建 RGBA 输出
|
||||
rgba = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
|
||||
rgba[:, :, :3] = image
|
||||
rgba[:, :, 3] = best_mask * 255
|
||||
|
||||
return rgba
|
||||
```
|
||||
|
||||
### 工作流 3:医学图像分割
|
||||
|
||||
```python
|
||||
# 处理医学图像(灰度转 RGB)
|
||||
medical_image = cv2.imread("scan.png", cv2.IMREAD_GRAYSCALE)
|
||||
rgb_image = cv2.cvtColor(medical_image, cv2.COLOR_GRAY2RGB)
|
||||
|
||||
predictor.set_image(rgb_image)
|
||||
|
||||
# 分割感兴趣区域
|
||||
masks, scores, _ = predictor.predict(
|
||||
box=np.array([x1, y1, x2, y2]), # ROI 边界框
|
||||
multimask_output=True
|
||||
)
|
||||
```
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 掩码数据结构
|
||||
|
||||
```python
|
||||
# SamAutomaticMaskGenerator 输出
|
||||
{
|
||||
"segmentation": np.ndarray, # H×W 二值掩码
|
||||
"bbox": [x, y, w, h], # 边界框
|
||||
"area": int, # 像素数量
|
||||
"predicted_iou": float, # 0-1 质量分数
|
||||
"stability_score": float, # 0-1 鲁棒性分数
|
||||
"crop_box": [x, y, w, h], # 生成裁剪区域
|
||||
"point_coords": [[x, y]], # 输入点
|
||||
}
|
||||
```
|
||||
|
||||
### COCO RLE 格式
|
||||
|
||||
```python
|
||||
from pycocotools import mask as mask_utils
|
||||
|
||||
# 将掩码编码为 RLE
|
||||
rle = mask_utils.encode(np.asfortranarray(mask.astype(np.uint8)))
|
||||
rle["counts"] = rle["counts"].decode("utf-8")
|
||||
|
||||
# 将 RLE 解码为掩码
|
||||
decoded_mask = mask_utils.decode(rle)
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### GPU 内存
|
||||
|
||||
```python
|
||||
# 在 VRAM 有限时使用较小模型
|
||||
sam = sam_model_registry["vit_b"](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/segment-anything/checkpoint="sam_vit_b_01ec64.pth")
|
||||
|
||||
# 批量处理图像
|
||||
# 在大批量之间清空 CUDA 缓存
|
||||
torch.cuda.empty_cache()
|
||||
```
|
||||
|
||||
### 速度优化
|
||||
|
||||
```python
|
||||
# 使用半精度
|
||||
sam = sam.half()
|
||||
|
||||
# 减少自动生成的点数
|
||||
mask_generator = SamAutomaticMaskGenerator(
|
||||
model=sam,
|
||||
points_per_side=16, # 默认为 32
|
||||
)
|
||||
|
||||
# 使用 ONNX 进行部署
|
||||
# 导出时加 --return-single-mask 以加快推理速度
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 问题 | 解决方案 |
|
||||
|-------|----------|
|
||||
| 内存不足 | 使用 ViT-B 模型,缩小图像尺寸 |
|
||||
| 推理缓慢 | 使用 ViT-B,减小 points_per_side |
|
||||
| 掩码质量差 | 尝试不同 prompt,使用框 + 点组合 |
|
||||
| 边缘伪影 | 使用 stability_score 过滤 |
|
||||
| 小对象漏检 | 增大 points_per_side |
|
||||
|
||||
## 参考资料
|
||||
|
||||
- **[高级用法](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/segment-anything/references/advanced-usage.md)** - 批处理、微调、集成
|
||||
- **[故障排查](https://github.com/NousResearch/hermes-agent/blob/main/skills/mlops/models/segment-anything/references/troubleshooting.md)** - 常见问题与解决方案
|
||||
|
||||
## 资源
|
||||
|
||||
- **GitHub**:https://github.com/facebookresearch/segment-anything
|
||||
- **论文**:https://arxiv.org/abs/2304.02643
|
||||
- **演示**:https://segment-anything.com
|
||||
- **SAM 2(视频)**:https://github.com/facebookresearch/segment-anything-2
|
||||
- **HuggingFace**:https://huggingface.co/facebook/sam-vit-huge
|
||||
Reference in New Issue
Block a user