Open-LLM-VTuber 报错排查:JSON 嵌套层级与 BOM 隐形字符
在 Windows + Docker 环境下部署 Open-LLM-VTuber (v1.2.1) 搭建2D虚拟数字人,Live2D 初始化阶段容易出现一个错误。控制台会输出如下信息:
CRITICAL | src.open_llm_vtuber.service_context:init_live2d:320 | Error initializing Live2D: string indices must be integers
排查底层逻辑后发现,主要由两个因素叠加引起:model_dict.json 嵌套层级错误,以及 Windows 环境下文件编辑引入的 BOM 隐形字符。
1. JSON 嵌套层级错误
在配置自定义 Live2D 模型路径时,开发者习惯按照键值对的方式写入文件:
// 错误写法
{
"witch": "live2d-models/witch/witch.model3.json"
}
程序后端的解析器会读取这个配置并尝试提取字典中的属性。当后端的 Python 逻辑试图通过 config["witch"]["path"] 提取具体路径时,由于 config["witch"] 只是一个字符串,系统将其视为对字符串进行切片操作,从而抛出 string indices must be integers 异常。
正确的数据结构需要多包裹一层对象:
// 正确写法
{
"witch": {
"path": "live2d-models/witch/witch.model3.json"
}
}
2. UTF-8 BOM 隐形字符干扰
即便 JSON 格式完全正确,有些环境依然会报错 witch not found in model dictionary。问题出在文件编码上。
如果在 Windows 下使用自带的记事本修改 model_dict.json,系统默认会以带 BOM(Byte Order Mark)的 UTF-8 格式保存。文件头部会被隐式插入 \xef\xbb\xbf 字符。
Python 原生的 json.load() 解析这类文件时,会将 BOM 字符识别为第一个 Key 的一部分。原本的键名 "witch" 会变成 "\ufeffwitch"。后续在代码中通过 if "witch" in model_dict: 进行判断时,结果恒为 False,导致路径解析失败。
处理方式: 使用 VS Code 或类似编辑器打开 model_dict.json。检查右下角的编码格式,将其从 UTF-8 with BOM 更改为 UTF-8(或 Save with Encoding 选择 UTF-8),重新保存文件后重启容器。
3. 规避解析器的替代方案
如果项目底层逻辑对配置文件的要求过于严苛,直接绕过解析层是更高效的工程实践。
Open-LLM-VTuber 预置了一个名为 mao_pro 的官方模型作为 fallback 选项。可以采用以下操作跳过上述所有 JSON 校验:
-
进入
models/目录,将自定义 Live2D 模型文件夹重命名为mao_pro。 -
将目录内的
.model3.json主文件重命名为mao_pro.model3.json。 -
删除
conf/model_dict.json文件。 -
在
conf.yaml中将live2d_model_name设为mao_pro。
删除映射文件后,后端会跳过索引查找,直接加载重命名后的物理路径。