Embedding 模型可移植性
本指南介绍如何将 embedding 模型纳入项目管理,并通过 resources/models/ 目录实现可迁移与 air-gapped(无网络)环境部署。
概述
默认情况下,sentence-transformers 模型缓存在 ~/.cache/huggingface/hub/,迁移到新机器时模型文件不会随项目一起迁移。通过以下改造,模型文件存放在项目本地 resources/models/ 目录,并在容器运行时以挂载目录或预置目录方式读取。
目录结构
resources/
└── models/
└── sentence-transformers/
└── all-MiniLM-L6-v2/
├── config.json
├── model.safetensors
├── tokenizer.json
├── tokenizer_config.json
└── ...
resources/ 目录已加入 .gitignore(模型文件太大不适合 git 管理),建议通过部署时挂载目录来提供模型文件。
快速开始
1. 下载模型到本地
uv run python scripts/download_embedding_model.py
脚本会读取 config.toml 中的 [embedding] 配置,将模型下载到 resources/models/ 目录。
2. 构建 Docker 镜像
docker compose build ai-service
ai_service 镜像会预创建 /app/resources/models 目录;若在 Compose 中挂载 ./resources:/app/resources,则容器将直接读取宿主机模型文件。
默认构建不包含 local_embedding 依赖组(包含 sentence-transformers 等重依赖)以减小镜像体积。若需要在容器内启用本地 embedding,请使用:
docker build -f ai_service/Dockerfile --build-arg ENABLE_LOCAL_EMBEDDING=true -t ai-service:local-embedding .
3. 启动服务
docker compose up ai-service
容器启动后,embedding 服务优先从本地目录加载模型,无需网络访问。
配置
config.toml
[embedding]
model = "sentence-transformers/all-MiniLM-L6-v2"
dim = 384
offline_mode = true
model_dir = "resources/models"
| 配置项 | 说明 | 默认值 |
|---|---|---|
model |
HuggingFace 模型名称 | sentence-transformers/all-MiniLM-L6-v2 |
dim |
向量维度 | 384 |
offline_mode |
是否禁止网络请求 | true |
model_dir |
项目本地模型存储目录(相对于项目根目录) | resources/models |
环境变量覆盖
所有 [embedding] 配置项均可通过 EMBEDDING_ 前缀的环境变量覆盖:
EMBEDDING_MODEL_DIR=resources/models
EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
EMBEDDING_DIM=384
EMBEDDING_OFFLINE_MODE=true
模型加载优先级
EmbeddingService._load_model() 按以下顺序加载模型:
- 项目本地目录:检查
{project_root}/{model_dir}/{model_name}路径是否存在,存在则直接从本地加载 - HuggingFace 缓存:本地目录不存在时,fallback 到
~/.cache/huggingface/hub/缓存(offline_mode=true时使用local_files_only=True) - 在线下载:
offline_mode=false时,从 HuggingFace Hub 在线下载
加载日志会明确标注模型来源:
Loading embedding model: sentence-transformers/all-MiniLM-L6-v2 (source=local dir (/app/resources/models/sentence-transformers/all-MiniLM-L6-v2), timeout=300s, offline=True)
下载脚本详解
scripts/download_embedding_model.py 支持以下参数:
# 使用 config.toml 默认配置
uv run python scripts/download_embedding_model.py
# 指定模型和输出目录
uv run python scripts/download_embedding_model.py \
--model sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 \
--output-dir resources/models
# 强制重新下载
uv run python scripts/download_embedding_model.py --force
| 参数 | 说明 |
|---|---|
--model |
HuggingFace 模型名称(覆盖 config.toml) |
--output-dir |
目标目录(覆盖 config.toml) |
--force |
即使目标目录已有模型文件也重新下载 |
脚本会在下载完成后自动验证模型可加载并输出 embedding 维度。
支持 HF_ENDPOINT 环境变量使用镜像站加速:
HF_ENDPOINT=https://hf-mirror.com uv run python scripts/download_embedding_model.py
更换 Embedding 模型
更换模型只需三步:
-
修改
config.toml中的model和dim:[embedding] model = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" dim = 384 -
运行下载脚本:
uv run python scripts/download_embedding_model.py -
重新构建 Docker 镜像:
docker compose build ai-service
更换模型后需重建向量索引
更换 embedding 模型后,已有的 Qdrant collection 中的向量与新模型不兼容,需要手动重建索引。
变更文件清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
config.toml |
修改 | 新增 model_dir = "resources/models" |
ai_service/utils/settings.py |
修改 | EmbeddingSettings 新增 model_dir: str 字段 |
ai_service/services/embedding.py |
修改 | _load_model() 支持从 model_dir 优先加载 |
ai_service/Dockerfile |
修改 | 创建 resources/models 目录,避免依赖构建上下文中的 resources/ |
docker-compose.yml |
修改 | 开发模式挂载 ./resources:/app/resources |
scripts/download_embedding_model.py |
新增 | 模型下载与验证脚本 |
.gitignore |
修改 | 添加 resources/ |
.dockerignore |
新增 | 排除常见构建产物 |
.env.example |
修改 | 添加 EMBEDDING_MODEL_DIR 说明 |