现象
本地 ASR 模型下载在「目标文件已存在」时直接跳过,不校验文件大小。若上一次下载被中断或文件被外部损坏后仍残留为目标文件,会被当成「已下完」跳过;模型加载时才以含糊错误失败。
根因(已读源码确认)
asr/local/download.rs 的 run_download:
let dest = dir.join(&file.path);
if dest.exists() {
// 已经下完的跳过
continue; // ← 不比对 file.size
}
仅凭 dest.exists() 判定完整,不同于 sherpa_download 的 verify_file。file.size(HF 给出的期望大小)此处可用却未用。注:多块下载路径(download_one)末尾其实有 actual != total_size 的校验,缺口主要在这个「已存在即跳过」分支。
影响
被截断 / 损坏的已存在模型文件被信任为完整、跳过重下,下次运行仍被信任,最终在模型加载时失败且错误信息含糊,用户难自查。
修法(单一职责)
抽纯函数 existing_file_is_complete(actual_size, expected_size):
- 大小一致 → 完整;
- 大小不符(截断/损坏)→ 不完整;
expected_size == 0(HF 未给大小)→ 退回旧行为「存在即信任」,避免对未知大小文件反复重下;
- 元数据取不到 → 不完整。
run_download 在 dest.exists() 时按它判定:完整才跳过,否则删除残留文件重新下载。
验证
existing_file_is_complete 真值表单测(一致/截断/超大/无元数据/未知大小)。cargo test --lib 全绿。
来源:2026-06-16 全仓多 Agent 审计(asr-local 专项)。
现象
本地 ASR 模型下载在「目标文件已存在」时直接跳过,不校验文件大小。若上一次下载被中断或文件被外部损坏后仍残留为目标文件,会被当成「已下完」跳过;模型加载时才以含糊错误失败。
根因(已读源码确认)
asr/local/download.rs的run_download:仅凭
dest.exists()判定完整,不同于sherpa_download的verify_file。file.size(HF 给出的期望大小)此处可用却未用。注:多块下载路径(download_one)末尾其实有actual != total_size的校验,缺口主要在这个「已存在即跳过」分支。影响
被截断 / 损坏的已存在模型文件被信任为完整、跳过重下,下次运行仍被信任,最终在模型加载时失败且错误信息含糊,用户难自查。
修法(单一职责)
抽纯函数
existing_file_is_complete(actual_size, expected_size):expected_size == 0(HF 未给大小)→ 退回旧行为「存在即信任」,避免对未知大小文件反复重下;run_download在dest.exists()时按它判定:完整才跳过,否则删除残留文件重新下载。验证
existing_file_is_complete真值表单测(一致/截断/超大/无元数据/未知大小)。cargo test --lib全绿。