Skip to content

[Enhancement] 本地模型下载断点续传与重试——大文件 fetch 中途 terminated #194

Closed

Description

@modusensus

来源:#188 补充 3(与核心修复分开跟进)。

现状

transformers.js 经 Node fetch 下载模型大文件(如 model.onnx 约 1GB)时,底层 undici socket 可能中途被重置,报 TypeError: terminated,整个下载作废重来;#188 报告者实测 curl -C - 可稳定完成,说明服务端支持 Range 续传。

期望

provision / 首次下载路径具备韧性,候选方向(实现时再定):

  1. 下载失败自动重试(有限次 + 退避);
  2. 断点续传:基于 HTTP Range 从已落盘字节继续;
  3. 至少把「下载失败于 X%」写进日志,让用户能判断是网络问题还是磁盘问题。

范围说明

transformers.js 内部下载不易注入,可能要走 mneme-runtime.mjs 的自管 provision 路径预取模型文件,或给 env 层替换 fetch 实现——需要先摸清 transformers 4.2.0 的可注入面,改动面不小,值得单独设计。

Activity

  1. heptaspirit commented on Sep 16, 2026

    @heptaspirit
    Collaborator

    摸了下注入面,结论是这层能做:4.2.0 的模型下载必经 env.fetch(src/utils/hub.js 的 getFile()),而 env.fetch 是官方文档化的可替换项,transformers.js 本体不用动。我们把运行时取件层已有的 Range 续传思路搬到了这一层,fork 里已实现并全量测试通过,PR #207。

    方案(env.fetch 外包一层):

    • 断点按 URL sha256 落盘在模型缓存旁,跨进程重启也能续上;
    • Range/If-Range 续传,206 追加、200/失配重来——内容被替换时宁可整份重来,不拼损坏文件;
    • 空闲看门狗代替总时长超时,慢而健康的下载不会被误杀;
    • 失败日志带「中断于 X%」,重试耗尽的错误也带位置(issue 里的第③点);
    • 对 transformers.js 恒以规范 200 出现(hub 把非 200 当失败,206 不能透传)。

    本地仿真(100MB 文件、每 30MB 掐断;terminated 的公网抖动没法本地稳定复现,如实说明。服务端支持 Range 这点与报告者 curl -C - 的实测一致):

    场景 现状(整份重来) 续传
    掐断 2 次 累计 160MB 100MB
    掐断 4 次 累计 220MB 100MB

    两者结果 sha256 一致;续传版传输量恒等于文件大小。1GB 断在 80% 的场景,现状就是 800MB 白费。

    开关 resilientModelDownload 默认开、面板可关,默认值想听听维护者的意见。测试 11 例(断流续传 / 206·200·416 / If-Range 失配 / 看门狗 / 并发锁等),全仓 1072 用例 1070 绿(1 fail 是本地沙箱 spawn 子进程限制,1 skip 既有)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions