LoHoSearch评估过程中常见异常及处理方法

文章导读
LoHoSearch 评估过程中出现的异常,通常集中在数据格式、执行环境和结果解析三个层面。定位时建议先看评估日志和中间产物,确认异常能在小样本上复现,再决定下一步操作;直接调大超时或忽略异常样本,容易把问题掩盖到最终评分里。
📋 目录
  1. 评估启动前:环境变量与输入数据
  2. 执行过程中:超时、内存与并发冲突
  3. 评估结果里:空结果、低分和分数波动
  4. 建立一套标准排查流程
A A

LoHoSearch 评估过程中出现的异常,通常集中在数据格式、执行环境和结果解析三个层面。定位时建议先看评估日志和中间产物,确认异常能在小样本上复现,再决定下一步操作;直接调大超时或忽略异常样本,容易把问题掩盖到最终评分里。

处理 LoHoSearch 评估异常时,优先按 日志 → 输入数据 → 运行参数 → 评分脚本 的顺序排查。能复现的问题才值得改配置;临时跳过异常样本、提高超时只能止血,不能当作最终处理。具体根因需要结合当前环境确认。

评估启动前:环境变量与输入数据

评估任务启动后立即退出,最常见原因是找不到配置文件、索引路径或依赖目录。LoHoSearch 评估脚本通常会从环境变量或启动参数读取基础路径,可以先确认 LOHO_SEARCH_HOMELOHO_INDEX_DIR 一类变量是否正确设置。检查方法很简单:在启动评估前执行 echo $LOHO_SEARCH_HOME,确认路径存在且当前用户有读写权限。如果路径没问题,再看配置文件里的路径是否包含软链接或相对路径,评估进程的工作目录不同会导致相对路径解析失败。

输入数据的问题也很常见。评估查询一般使用 JSONL、CSV 或特定分隔符文本。遇到“读取到空行”或“字段缺失”的报错时,不要直接修改评估脚本,先查看原始文件的前几行。例如:

head -c 2000 eval_queries.jsonl

如果文件来自 Windows,可能带有 CRLF 换行和 BOM,可以用 file eval_queries.jsonl 查看编码,用 sed -i 's/\r$//' eval_queries.jsonl 在副本上去除回车符。注意备份原文件。

建议在评估入口前增加一个字段校验步骤,避免把坏数据带进流程。示例校验脚本:

import json
with open('eval_queries.jsonl', encoding='utf-8') as f:
    for i, line in enumerate(f, 1):
        try:
            obj = json.loads(line)
            assert 'query' in obj and 'expected_doc' in obj
        except Exception as e:
            print(f'line {i}: {e}')

这个脚本只验证必需字段,执行时若报错就能定位到具体行号。编写校验逻辑时,字段名需要结合当前评估配置确认,不要假设所有格式都相同。

执行过程中:超时、内存与并发冲突

评估任务运行中卡住,优先判断是查询量太大、索引加载慢,还是产生了死锁或等待。可以先看进程状态和日志尾部:

ps -o pid,etime,rss,cmd -p $(pgrep -f loho_eval)
tail -n 50 loho_eval.log

如果日志长时间没有新输出,可以用 jstackpy-spy dump 查看线程栈,确认线程停在网络请求、文件锁还是 GC。不要立刻用超时参数把任务杀掉,应先确认是否处于正常的数据排序阶段。若确认是死锁,需要检查评估过程是否对共享临时文件同时写入。

内存不足通常表现为 OutOfMemoryError 或 RSS 持续增长。先检查评估数据是否一次全部载入内存。LoHoSearch 的评估脚本可能会把查询集和候选文档都缓存在内存里,小样本验证通过但全量运行时失败。处理方向是把数据按日期或类别分片执行,或调整 JVM/进程的堆内存参数。但调大内存能解决问题时,也要记录下当前数据量对应的内存占用,避免后续低估。

LoHoSearch评估过程中常见异常及处理方法

并发评估时常见异常是多个任务写同一个临时目录。日志里通常出现“File exists”或“Permission denied”,但线程都在运行。建议为每个评估进程单独设置 `--workdir` 参数,或者把临时目录路径中包含当前 PID。没有此参数时,可以在包装脚本中创建 /tmp/loho_eval_$RANDOM 并作为环境变量传入。

评估结果里:空结果、低分和分数波动

查询全部或部分返回空结果,先区分是检索阶段没产出,还是评估脚本把结果过滤掉了。可以在评估输出中记录检索原始条数,如果原始条数为 0,则问题在索引或查询预处理;如果原始条数大于 0 但评估结果为 0,则问题在过滤条件,比如只保留特定类型文档或最低相关性阈值过高。检查过滤阈值时,先查看当前配置里 min_relevance_scoretop_k 等参数,不要直接降低到 0。

评分普遍偏低,不代表评估异常,先拿一个已知样例人工核对。如果人工判断相关性正常,但分数低,可能是指标计算方式与标注意图不匹配,比如标注的是文档级相关,而评估默认假设置顶位置相关。需要确认使用的评估指标和期望口径。如果标注文件中的标签是 0/1,但脚本读取为字符串,也会导致匹配失败,评分变成 0。

多次运行评分波动,通常与样本顺序、随机负采样或模型推理的并行开关有关。如果评估脚本有 seed 参数,固定为同一个值再对比结果。如果没有固定随机种子,且数据量较小,波动是正常的。若要比较不同配置的效果,至少保证同一组查询和顺序,在日志中记录本次运行的查询 hash 或样本条数。

建立一套标准排查流程

遇到 LoHoSearch 评估异常,建议按以下步骤推进:先复现异常,使用一个较小的查询子集运行,复现时间尽量短;同时保留出错时的日志和配置快照,至少记录评估入口命令、数据集文件名和运行时间。然后检查输入数据格式和路径,再检查资源占用与并发冲突;如果以上都没有异常,最后检视评分脚本和指标定义。

下面是一个简单的排查判断表,只列出初步检查点和处理方向。

现象初步检查处理方向
启动即退出环境变量、路径权限、依赖库补齐配置或重新安装依赖
运行中途卡住日志时间戳、线程栈确认死锁或长时间 GC
内存溢出数据集大小、JVM 参数分片执行或提高堆内存
全部空结果索引存在性、查询预处理检查查询分析器与索引段
评分过低或波动标注格式、随机种子固定种子并核对指标口径

这个表只用于缩小排查范围,不是定论。比如“启动即退出”也可能由其他原因引起,需要结合当前环境的错误信息确认。另外,调整任何参数后,都要用同一个样本集和同一组查询重新跑一遍,确认异常是否仍然存在。保留原始数据和修正后数据的统计结果,方便后续回看。

如果问题在评估脚本本身,不要通过放宽异常跳过条件来达到“通过运行”。比如某个样本导致评分脚本抛异常,脚本提供了 `--skip`_errors 参数,使用后确实能继续运行,但最终评分会缺失部分样本。建议先修正脚本中对缺失字段或空列表的处理逻辑,或将该样本单独分析。