本文详解在 pyvespa 中部署 onnx 模型时常见的路径引用错误,指出应用包内不可使用宿主机或 docker 卷路径,所有模型文件必须打包进应用 zip 并通过相对路径引用,同时提供可运行的 schema 配置与部署实践要点。
本文详解在 pyvespa 中部署 onnx 模型时常见的路径引用错误,指出应用包内不可使用宿主机或 docker 卷路径,所有模型文件必须打包进应用 zip 并通过相对路径引用,同时提供可运行的 schema 配置与部署实践要点。
在使用 PyVespa 将 ONNX 模型集成至 Vespa 向量数据库时,一个高频报错是 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)。该错误并非 JSON 格式问题本身,而是 Vespa 部署流程中因模型路径解析失败导致服务端返回空响应(HTTP 200 但 body 为空),进而触发客户端 JSON 解析异常。
根本原因在于:Vespa 应用包(.zip)是一个自包含部署单元,所有资源(包括 ONNX 模型文件)必须显式纳入包内,且只能通过相对于 schemas/ 或 models/ 目录的相对路径引用。以下写法是错误的:
# ❌ 错误:指向宿主机绝对路径或 Docker 卷路径(Vespa 容器内不可见)
self.app_package.schema.add_model(
Model(
name="finance_embedding",
model_file="/local/path/to/model.onnx" # → 部署时将失效!
)
)
✅ 正确做法如下:
- 将 ONNX 文件置于项目目录下合适位置(如 models/finance_model.onnx);
- 在 app_package 初始化时显式添加模型文件:
from vespa.package import ApplicationPackage, Schema, Field, RankProfile, Model
def create_finance_app(self):
self.app_package = ApplicationPackage(name="finance")
# ✅ 正确:添加模型文件到应用包(自动打包进 .zip)
self.app_package.add_model(
Model(
name="finance_embedding",
model_file="models/finance_model.onnx" # ← 相对路径,从项目根开始
)
)
# 定义 schema 字段与 embedding 字段(需 match tensor type)
self.app_package.schema.add_fields(
Field(name="title", type="string", indexing=["index", "summary"]),
Field(
name="embedding",
type="tensor(x[1024])",
indexing=["attribute", "index"],
attribute=["fast-search"]
)
)
# 添加 rank profile,使用 closeness + query input
self.app_package.schema.add_rank_profile(
RankProfile(
name="default",
first_phase="closeness(field, embedding)",
inputs=[("query(query_embedding)", "tensor(x[1024])")]
)
)
self.app_package.schema.mode = "streaming"
- 确保部署前模型文件真实存在且路径可读,并在 deploy_app() 中调用标准部署流程:
def deploy_app(self, **kwargs):
# ✅ 确保 vespa-docker-container 已启动且资源充足(尤其内存 ≥ 4GB)
self.app_package.deployment_config.application_name = "finance"
self.app = self.app_package.deploy(
instance="finance-dev",
container_memory="4G", # 关键:ONNX 推理需足够内存
**kwargs
)
⚠️ 注意事项:
- Vespa 不支持直接挂载外部卷(如 -v /host/model.onnx:/opt/vespa/app/models/model.onnx)供 schema 引用;
- 若使用 add_model(),PyVespa 会自动将文件复制到 application/models/ 并在 services.xml 中注册 元素;
- ONNX 模型需满足 Vespa 的算子兼容性要求(推荐使用 onnxruntime 验证基础推理,并避免动态 shape、控制流等高级特性);
- 首次部署建议启用 verbose=True 查看 ZIP 打包内容,确认 models/finance_model.onnx 已包含其中。
总结:PyVespa 中 ONNX 集成的核心原则是 “打包即部署” —— 所有模型、配置、脚本必须作为应用包的一部分提交,而非依赖运行时外部路径。遵循此规范,即可规避 JSONDecodeError 及模型加载失败问题,实现端到端向量检索闭环。