模型服务端
模型服务器
相关源文件
以下文件为本维基页面的生成提供了上下文:
backend/model_server/constants.pybackend/model_server/encoders.pybackend/model_server/main.pybackend/model_server/management_endpoints.pybackend/model_server/utils.pybackend/onyx/natural_language_processing/constants.pybackend/onyx/natural_language_processing/search_nlp_models.pybackend/onyx/utils/gpu_utils.pybackend/onyx/utils/search_nlp_models_utils.pybackend/shared_configs/configs.pybackend/shared_configs/model_server_models.pybackend/tests/unit/model_server/test_embedding.pybackend/tests/unit/onyx/natural_language_processing/test_search_nlp_models.pybackend/tests/unit/onyx/utils/test_gpu_utils.py- [web/src/app/api/[...path]/route.ts](web/src/app/api/[...path]/route.ts)
模型服务器是一个独立的 FastAPI 应用程序,负责处理 AI/ML 推理操作。它与主 API 后端分开运行,目的是隔离 GPU 密集型工作负载并支持独立扩缩容。该应用程序定义在 backend/model_server/main.py 中,通过专门的编码器和自定义 NLP 任务路由器暴露端点。
该服务器提供以下功能:
- 文本嵌入向量生成:通过
SentenceTransformer模型实现高性能向量生成。backend/model_server/encoders.py:28-31 - 文档重排序:使用交叉编码器对搜索结果进行评分和优化。
backend/model_server/encoders.py:227-230 - 自定义 NLP 分类器:意图检测和关键词提取。
backend/model_server/encoders.py:257-260 - GPU 状态监控:提供端点检查硬件加速的可用性。
backend/model_server/management_endpoints.py:15-19
通过 INDEXING_ONLY 环境变量支持两种部署模式,用于将实时用户流量与后台处理任务分离。backend/shared_configs/configs.py:66-67
来源:backend/model_server/main.py:11-29、backend/shared_configs/configs.py:66-67、backend/model_server/encoders.py:28-31
应用架构
应用初始化
backend/model_server/main.py 中的 get_model_app() 函数负责创建 FastAPI 应用程序,并配置路由器、中间件和生命周期管理。
模型服务器组件架构
来源:backend/model_server/main.py:95-126、backend/model_server/encoders.py:25、backend/model_server/main.py:75
部署模式与主机配置
模型服务器支持通过 backend/shared_configs/configs.py 中的环境变量进行双部署配置。这使得系统可以将繁重的索引任务路由到单独的实例,避免它们对终端用户的聊天推理引入延迟。backend/shared_configs/configs.py:24-33
| 配置项 | 环境变量 | 默认值 | 用途 |
|---|---|---|---|
| 推理主机 | MODEL_SERVER_HOST | localhost | 用于实时聊天/搜索推理的主服务器。 |
| 索引主机 | INDEXING_MODEL_SERVER_HOST | 与推理主机相同 | 用于后台文档嵌入的专用服务器。 |
| 模式标志 | INDEXING_ONLY | false | 当设为 true 时,禁用非索引端点(重排序、意图识别)。 |
当设置 INDEXING_ONLY=true 时,add_onyx_request_id_middleware 会使用 "IDX" 前缀代替 "INF"。backend/model_server/main.py:117-121 此外,仅索引模式的模型服务器在用于重排序或意图分类时会抛出异常。backend/shared_configs/configs.py:64-66
来源:backend/shared_configs/configs.py:17-33、backend/shared_configs/configs.py:64-66、backend/model_server/main.py:117-121
应用生命周期与模型缓存
backend/model_server/main.py 中的 lifespan() 异步上下文管理器负责管理关键的启动任务,包括 GPU 检测和 HuggingFace 缓存管理。backend/model_server/main.py:70-92
启动序列
- GPU 检测:调用
get_gpu_type()识别可用的硬件(CUDA、MPS 或无),并将其存储在app.state.gpu_type中。backend/model_server/main.py:72-75backend/model_server/utils.py:66-72 - 线程配置:根据
MIN_THREADS_ML_MODELS设置torch.set_num_threads。backend/model_server/main.py:89 - HuggingFace 缓存合并:
Dockerfile.model_server会将模型预下载到临时目录。在启动时,_move_files_recursively将TEMP_HF_CACHE_PATH(.cache/temp_huggingface)合并到活动的HF_CACHE_PATH(.cache/huggingface)中。backend/model_server/main.py:78-82这确保了即使缓存目录上挂载了持久化卷,预置的模型仍然可用。
来源:backend/model_server/main.py:70-92、backend/shared_configs/configs.py:62、backend/model_server/main.py:35-36、backend/model_server/utils.py:66-72
嵌入向量生成
嵌入逻辑位于 backend/model_server/encoders.py 中。它使用全局字典 _GLOBAL_MODELS_DICT 来缓存 SentenceTransformer 实例,避免重复加载模型。backend/model_server/encoders.py:25-31
模型加载与预热
get_embedding_model 函数确保模型根据硬件正确初始化。
嵌入模型生命周期
RoPE 预热:_prewarm_rope 函数通过使用长文本执行一次虚拟推理来构建旋转位置嵌入(RoPE)的 cos/sin 缓存。backend/model_server/encoders.py:38-55 这可以防止第一个真实请求时出现延迟峰值。
来源:backend/model_server/encoders.py:28-78、backend/model_server/encoders.py:38-57
并发与重试
模型服务器使用线程池通过 run_in_executor 执行 CPU 密集型的嵌入任务。backend/model_server/encoders.py:142-147 由于底层的 transformers 库偶尔会遇到竞态条件(特别是 RuntimeError: Already borrowed),_concurrent_embedding 函数实现了重试机制。backend/model_server/encoders.py:85-99
| 设置项 | 值 |
|---|---|
ENCODING_RETRIES | 3 |
ENCODING_RETRY_DELAY | 0.1 秒 |
来源:backend/model_server/encoders.py:81-102、backend/model_server/encoders.py:142-147
Docker 配置与缓存
Dockerfile.model_server 是一个多阶段构建,通过预缓存权重来最小化运行时出站流量和启动时间。backend/Dockerfile.model_server:1-26
模型缓存(model_cache_huggingface)
为了支持离线或受限出站环境,构建过程会预下载默认的嵌入模型。
- 阶段:embedding-models:使用
huggingface_hub的snapshot_download获取nomic-ai/nomic-embed-text-v1。backend/Dockerfile.model_server:17-19 - 架构初始化:运行一次虚拟的
SentenceTransformer初始化,确保自定义远程代码(如果有)被缓存。backend/Dockerfile.model_server:22-23 - 存储:内容存储在
/app/.cache/huggingface。backend/Dockerfile.model_server:9 - 最终阶段:内容被移动到
temp_huggingface文件夹,以便在运行时与用户挂载的卷合并。backend/Dockerfile.model_server:44
来源:backend/Dockerfile.model_server:17-23、backend/Dockerfile.model_server:44、backend/model_server/main.py:78-82
Dockerfile 结构
最终镜像将 Python 依赖项与预缓存的模型和模型服务器源代码组合在一起。
来源:backend/Dockerfile.model_server:2-72、backend/model_server/main.py:49-67
端点与数据流
模型服务器暴露了多个用于处理文本的 POST 端点,这些端点定义在 backend/model_server/encoders.py 中。
双编码器嵌入(/encoder/bi-encoder-embed)
用于生成查询和文档片段的嵌入向量。它接受一个 EmbedRequest 并返回包含向量列表的 EmbedResponse。backend/model_server/encoders.py:176-181 它支持 Nomic 等模型所需的手动查询/片段前缀。backend/model_server/encoders.py:136-140
来源:backend/model_server/encoders.py:176-181、backend/model_server/encoders.py:136-140、backend/shared_configs/model_server_models.py:10-31
交叉编码器重排序(/encoder/cross-encoder-scores)
计算单个查询与多个文档之间的相似度分数。这在搜索管线中用于重新排序来自 Vespa 的顶部结果。 限制:如果 INDEXING_ONLY 为 true,此端点会被阻止。backend/model_server/encoders.py:227-241
来源:backend/model_server/encoders.py:227-241
意图分类(/encoder/intent-模型)
识别用户查询是基于关键词的意图还是语义意图,并提取关键词。 限制:如果 INDEXING_ONLY 为 true,此端点会被阻止。backend/model_server/encoders.py:257-270
来源:backend/model_server/encoders.py:257-270、backend/shared_configs/model_server_models.py:54-65
管理端点
- 健康检查(
/api/health):返回 200 状态码表示服务器正在运行。backend/model_server/management_endpoints.py:10-12 - GPU 状态(
/api/gpu-status):返回是否检测到 GPU(CUDA 或 MPS)以及具体的硬件类型信息。backend/model_server/management_endpoints.py:15-19
来源:backend/model_server/management_endpoints.py:10-19、backend/model_server/constants.py:4-7