mlsubgen — 在你自己的机器上为视频生成 45 种语言的字幕

Reddit r/LocalLLaMA 工具

摘要

mlsubgen 是一款开源命令行工具,完全在本地机器上为视频生成 45 种语言的字幕,采用基于 CUDA 的语音识别(Qwen3-ASR、Whisper large-v3)以及由 Ollama 托管的 LLM 翻译,并提供硬件配置方案,最低只需 8 GB 显存的 GPU。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/03 04:57

dodgypast/mlsubgen

来源:https://github.com/dodgypast/mlsubgen

mlsubgen — 为你的视频生成 45 种语言的字幕,全部在你自己的机器上完成

cd /some/folder/of/videos
mlsubgen

该文件夹及其子目录下的每个视频,都会生成一个 .srt 字幕文件,对应你要求的每种字幕语言(.en.srt、.th.srt …)。数据不会离开机器:语音由本地模型转写,翻译由本地 LLM 完成,唯一写入的文件就是视频旁边的那些 .srt。

mlsubgen = multi-language(多语言)+ machine-learning(机器学习)字幕生成器。

它最初是一个日文→英文的工具,用于个人视频库,后来发展为通用工具:它会检测每一段语音的语言,强制用该语言对每段进行转写,并为 45 种目标语言各自生成独立文件。

硬件要求

需求说明
GPU显存至少 8 GB 的 NVIDIA 显卡;完整质量配置需要 24 GB仅支持 CUDA——没有 AMD、Apple 或 Windows 路径,因为 ASR 引擎都是 CUDA 构建。显卡从不同时持有语音引擎和翻译器(一次运行会先转写一批文件,释放显卡,再进行翻译),所以它只需要能容纳较大的那个阶段。在 RTX A5000(24 GB)上开发并测量;较小的配置以更少的常驻显存运行同一套代码,仅经过轻度测试
RAM最低 16 GB,推荐 32 GB模型在进入显卡之前会经过内存;OCR 期间同时运行四个 tesseract 进程;在小显存显卡上,Ollama 放不下翻译器时会将一部分溢出到内存
CPU4 核或以上说话人分离、位图解码和 tesseract OCR 在 CPU 上运行,而非 GPU
磁盘根据配置 30–65 GBDocker 镜像约 14 GB(或宿主机上 venv 约 6 GB)· ASR 模型约 8 GB(Qwen3-ASR 及其对齐器、whisper large-v3)· Ollama 中的翻译器:full ≈ 37 GB(两个模型),12gb 7 GB,8gb 6 GB · 说话人模型 33 MB · tesseract 语言包约 0.5 GB · 每个视频的工作文件和 OCR 缓存几 MB;临时 wav 每小时视频约 120 MB,用完即删
操作系统 / 工具Linux;ffmpeg/ffprobe;同一宿主机上的 Ollama(https://ollama.com);带 NVIDIA Container Toolkit 的 Docker,或 Python 3.12 + uv(https://docs.astral.sh/uv/)用于宿主机安装在 Arch 系(CachyOS)和 Debian 系系统上测试

启动时会根据显存自动选择硬件配置(mlsubgen models 或 mlsubgen config 会显示;MLSUBGEN_PROFILE=12gb 或 --profile 12gb 可强制指定;mlsubgen pull 会下载当前配置所需的模型)。24 GB 以下的配置共用一个技巧,于 2026-10-03 测得:翻译器是 Gemma 4 的 26B 混合专家模型(gemma4:26b,磁盘占用 18 GB),其 30 层中只有能装下的部分放在显卡上,其余由 Ollama 从系统内存运行。由于它每个 token 只有约 4B 参数是激活的,大部分层不在显卡上也能保持快速——24 层常驻时生成速度为 84 tok/s,16 层时为 51,8 层时为 40(短提示,在一张 24 GB 显卡上限制为这些拆分方式测得)——而且翻译质量几乎与 31B 相当(同一段片段和参考文本的 chrF++ 为 30.2,而 31B 为 31.0;稠密的 12B 为 29.0),读取泰文、中文和日文位图的能力也完全相同(76% / 93.8,而 31B 为 77% / 93.7)。端到端计算,包含提示词,十分钟测试片段用 16gb 拆分(22 层)翻译成泰文只需 68 秒,26B 完全装在 24 GB 显卡上时需 31 秒,用 31B 则需 103 秒。代价是不放在显卡上的那部分需要系统内存:没有足够内存的机器会改用稠密的小模型(-dense 配置,内存不足时自动选择)。

full — 20 GB 及以上16gb — 15 到 20 GB12gb — 11 到 15 GB8gb — 11 GB 以下
显卡,例如RTX 3090 / 4090 / 5090,RTX A5000 / A6000,L4(24 GB)RTX 4080,4070 Ti Super,4060 Ti 16 GB,5070 Ti,RTX A4000,V100RTX 3060 12 GB,4070,3080 12 GB,5070RTX 3050 / 3070 / 4060(8 GB),2070 / 2080
该配置所需的系统内存16 GB16 GB24 GB(否则用 12gb-dense)32 GB(否则用 8gb-dense)
语音识别两个引擎常驻,whisper 用 float16(≈ 10 GB)两个引擎常驻,whisper 用 float16(≈ 10 GB)两个引擎常驻,whisper 用 int8(≈ 8 GB)显卡上一次只放一个引擎(≈ 5 GB,然后 ≈ 2.5 GB);同样的两个引擎,每个文件更慢
翻译日文→英文用 qwen3.8:27b,其余语言对用 gemma4:31b-it-qat,全部装在显卡上(测试片段:103 秒)gemma4:26b,30 层中 22 层装在显卡上(≈ 13 GB):测试片段 68 秒,实测gemma4:26b,14 层装在显卡上(≈ 9 GB):生成速度约 50 tok/s,片段约 100 秒gemma4:26b,6 层装在显卡上(≈ 5 GB):生成速度约 40 tok/s,片段约 2 分钟
翻译,-dense 备选——gemma4:12b-it-qat(7.2 GB):chrF++ 29.0gemma4:e4b-it-qat(6.1 GB):更弱
逐段语言检测是是是是
内嵌文本字幕(优先于音频使用)是是是是
位图字幕,拉丁 / 希腊 / 西里尔文(tesseract,CPU)是是是是
位图字幕,泰文 / 中文 / 日文 / 韩文 / 叠加标记文字(视觉模型)是——31B是——26B,效果与 31B 相当是——26B(12gb-dense 用 12B,可用但较弱)是——26B,速度较慢(8gb-dense:否,E4B 读不了;这些音轨会被跳过,转而转写音频)
说话人分离(CPU)是是是是
术语统一处理(人名全片只翻译一次)是是是是
bench / lidbench / ocrbench是是是是

这些层拆分方式为上下文窗口和视觉编码器留出了空间;速度数据来自一张限制为这些拆分方式的 24 GB 显卡,所以真实 16 GB 显卡在相同拆分下表现应该相近,CPU 和内存较慢/较小时则会更低。只有 full 配置在自己的硬件上连续运行过数周;其他配置运行的是同一套代码,只是显卡上的内容更少。mlsubgen bench 会在长时间运行之前显示每种选择在你自己的素材上的实际代价。

它的功能

  • 逐段检测语音语言,而非整个文件:一个包含英文采访片段的日语节目会被当作两种语言处理。只有当 Whisper 的语言概率、Qwen3-ASR 自身的解码以及词语的文字系统三方一致时,才会认定为某种语言。
  • 每个音频块都用两个语音识别引擎——Qwen3-ASR-1.7B(及其强制对齐器,用于词级时间戳)和 faster-whisper large-v3——在两者不一致时,由翻译 LLM 进行协调。音频块覆盖整个时间轴(只有处于噪声底限的片段会被跳过),因此压在音乐上的对白不会被 VAD 丢失。
  • 由 LLM 完成翻译(Ollama,或任何 OpenAI 兼容的服务器),以 20 条字幕为窗口、带滚动上下文、人名术语表、按语言的语域规则(泰文语气词、du/Sie、简体 vs 繁体中文……),以及对模型遗漏内容的逐行降级处理。
  • 45 种字幕语言,在 Web UI 中勾选或用 --target en,th,de 按任务选择;已经是目标语言的字幕会直接复制,不进行翻译。
  • 按语言的字幕排版:行宽随文字系统调整、阅读速度上限(CJK 语言更宽松)、最小持续时间和间隔,以及为泰文、老挝文、高棉文、缅甸文和天城文提供的聚类安全换行。
  • 可选的说话人分离——sherpa-onnx 在 CPU 上本地识别说话人切换。说话人变化能让语言检测和字幕边界更精确,并为翻译器提供匿名的说话人连续性;不确定的说话人信息会被标为未知,而非强行归类。--speakers auto,或已知人数时用 --speakers N。详见下文说话人部分。
  • 内嵌字幕优先于音频:已经带有目标语言完整字幕的视频在该目标语言上会被直接跳过;45 种语言中任何其他完整文本音轨(非强制字幕、非仅对白和歌曲)都会被当作转写文本来源进行翻译,优先使用所讲语言的音轨。无需花时间做 ASR,也不会在原文已存在的情况下翻译翻译稿。
  • 带 Web UI 的任务队列:任务在 GPU 上逐个运行,能扛过重启(每个完成的阶段和每个解码的 ASR 音频块都有检查点),并且可以暂停和恢复。暂停的任务在重启后会一直保持在队列之外,直到你恢复它。

安装 — Docker

git clone https://github.com/dodgypast/mlsubgen.git && cd mlsubgen
cp .env.example .env
# MEDIA_DIR = 你的视频所在文件夹;默认语言;你的 uid/gid
mkdir -p data models
# 状态和模型缓存,由你创建,以便容器可以写入
docker compose up -d --build
# 镜像约 14 GB(CUDA torch 和 ASR 组件),首次 10–20 分钟
docker compose run --rm worker pull
# ASR 模型(约 8 GB)和两个默认翻译器(约 37 GB,装入 Ollama)

或者打开 http://:8790,使用 Models 面板:它会显示哪些模型已就绪,缺失的可以一键下载并显示进度。模型就绪后 worker 会立即使用。容器使用宿主机网络(Ollama 在 127.0.0.1:11434);Web UI 没有登录,所以请将它放在局域网或 VPN 地址上。你的视频被挂载到 /media,MLSUBGEN_MEDIA_ROOTS=/media 将文件夹选择器和 worker 限制在该目录内。停止 worker 容器会干净地中断正在运行的任务;下次启动时会从检查点继续。

安装 — 宿主机

git clone https://github.com/dodgypast/mlsubgen.git ~/mlsubgen && cd ~/mlsubgen
bash setup.sh
# venv、CUDA torch、固定版本的依赖、自检、`mlsubgen` 命令、两个用户级 unit

setup.sh 结束时会列出剩余步骤:编辑两个 unit 文件(MLSUBGEN_MEDIA_ROOTS、MLSUBGEN_TARGETS),用 mlsubgen pull 下载模型,然后 systemctl --user enable --now mlsubgen-worker mlsubgen-web。

使用方法

mlsubgen
# 该目录及以下的所有视频 → 默认语言;排队交给 worker
mlsubgen --target en,th,de .
# 每个视频生成三个字幕文件
mlsubgen --source ja FOLDER
# 跳过语言检测:音频是日语
mlsubgen --overwrite FILE
# 从头重新处理一个文件
mlsubgen --speakers auto FOLDER
# 带说话人分离(需要先 mlsubgen pull speakers);已知人数时用 --speakers 3
mlsubgen languages
# 45 种语言代码、它们的原生名称、每种由哪个引擎解码
mlsubgen config targets th,de
# 保存默认语言(Web 表单中有"设为默认"选项);config 会显示所有设置
mlsubgen models
# 显示就绪状态:Ollama 中的翻译器、缓存中的 ASR 模型
mlsubgen pull
# 下载默认运行所需的模型;pull gemma4 · pull some/tag:latest · pull --all
mlsubgen jobs
# 队列;mlsubgen log ID · pause ID · resume ID · cancel ID · retry ID
mlsubgen help
# 单屏指南;mlsubgen help run 查看所有选项

worker 服务运行期间,在文件夹中执行 mlsubgen 会将任务加入队列并返回;worker 会运行它,Web UI 会显示每个文件的处理结果和实时日志。mlsubgen --now ... 则改为在前台运行。

Web UI

新建任务表单(文件夹选择器被限制在你的媒体根目录内,字幕语言勾选框,如需覆盖检测器可指定所讲语言、翻译器、ASR 模式、说话人分离、内嵌字幕策略、上下文、术语表),一个 Preview(试运行) 会列出该任务将涉及的确切文件,任务队列支持暂停 / 恢复 / 取消 / 重试,任务页面显示每个文件的结果和实时日志,以及一个已跳过文件的页面,可强制指定语言后重新排队。

处理流程

阶段内容
内嵌字幕目标语言中的文本音轨 → 该目标语言即已完成;其他任何完整文本音轨(45 种语言;所讲语言的优先;清理掉 ASS 中的标签、卡拉 OK 和注释)→ 作为转写文本,无需 ASR。无标签的文本音轨会从其自身文字内容推断语言。位图(PGS)音轨通过 OCR 读取(0.4.8):若为目标语言则直接生成该语言的 .srt,若为所讲语言则作为转写文本——参见位图字幕部分
探测ffprobe 选择音频音轨(先标签,再标题,最后默认)——mlsubgen tracks FILE 会显示各音轨,--audio-track N 可覆盖
音频ffmpeg → 16 kHz 单声道 wav;该文件的分离和 ASR 完成后即删除
说话人可选,--speakers:sherpa-onnx 在 CPU 上识别说话人切换,在任何内容听取文字之前完成;参见说话人部分
语言识别每约 10 秒语音一段——若说话人切换已知,则按说话人切换分段:Whisper 概率 + Qwen 解码 + 文字系统和虚词;切换点会被精确到具体范围;另一种语言的短暂片段需要强证据才会认定
音频块≤ 30 秒,每块一种语言(语言变化必然切分),覆盖整个时间轴;只有处于噪声底限的片段会被跳过
ASR两个引擎各自解码每个音频块,强制指定语言;每个音频块后生成检查点
合并翻译 LLM 协调两份转写文本的不一致之处(一致的音频块无需 LLM)
词 ↔ 说话人使用 --speakers 时:每个对齐的词取其明确覆盖的说话人段次,否则保持未标注
字幕切分句末、停顿、说话人切换、长度限制、幻觉过滤(证据门控)
翻译按目标语言分别处理:已是目标语言的字幕直接复制;其余以 20 条为窗口,带上下文、术语表、语域规则、说话人连续性、重试和逐行降级
排版≤ 2 行,按语言调整行宽和阅读速度,最小持续时间和间隔 → ..srt

不使用 --speakers 时,两个说话人相关行不会运行,其余部分不变。

位图字幕

蓝光重封装文件以 PGS 位图形式携带字幕,常常包含十几种语言,完全没有文本音轨;在 0.4.8 之前,mlsubgen 无法利用其中任何一个——一部带有英文字幕的影片仍会被重新转写。现在位图音轨可以通过 OCR 读取(--ocr auto,默认值;--ocr off 恢复旧行为):

  • 位于目标语言中的位图音轨会直接 OCR 生成该目标语言的 .srt——真实字幕,无需翻译(该语言中的文本音轨仍然优先,只有在没有文本音轨时位图目标音轨才被采用);
  • 位于所讲语言中的位图音轨(或在找不到时按常见来源顺序选取)会成为其他目标语言的翻译依据——带 OCR 噪声的人工字幕仍然优于机器转写。

mlsubgen 自行解码 PGS 流(合成、调色板、行程编码对象),并将每张字幕图像交给针对该文字系统实测效果最好的引擎:

文字系统引擎实测结果(字幕行精确匹配 / chrF)
拉丁、希腊、西里尔tesseract 及对应语言包(Arch 上为 tesseract-data-,Debian 上为 tesseract-ocr-;Docker 镜像自带 19 种)——CPU,一次处理四张图英文蓝光,1,800 条字幕:95% / 99.4
泰文、中文、日文、韩文,以及带叠加标记的文字(老挝文、高棉文、缅甸文、印度系文字、阿拉伯文、希伯来文)该硬件配置的视觉模型通过 Ollama 调用(full 用 gemma4:31b,12gb 用 12b)——GPU 上每秒一张图;在 ASR 引擎加载前卸载泰文:31B 77% / 93.7,12B 65% / 89.3;简体中文:31B 79% / 90.0;日文(用某蓝光 SDH 音轨与另一发行商的 SDH 转写文本对比,去除描述和标签后):31B 51% 字幕行完全相同 / chrF 78——差距在于蓝光盘在加入下一行的同时保留了前一行在屏幕上的时间、另一份转写缺少的插入语,以及模型正确省略的假名;配对的行在字符级别上能够吻合。相同情况下 tesseract 的结果为:泰文 50 / 71,中文 41 / 78
8gb 配置下的上述文字系统没有可用引擎——E4B 读取泰文的准确率为 18% / 66.5,不足以作为翻译依据;该音轨会被跳过,转而转写音频,与 0.4.8 之前的行为一致
结果会缓存在工作文件旁边,因此一个音轨

相似文章

SubtitleGenerator

Product Hunt

SubtitleGenerator是一款基于浏览器的工具,可利用人工智能从视频中生成可直接发布的字幕。

**破除巴别塔:面向长文本字幕翻译的自进化多智能体系统**

Hugging Face Daily Papers

该论文提出了 SMART,一个用于长篇字幕翻译的自演化多智能体系统。该系统采用测试时训练机制,结合动态路由器、Mixture-of-Agents 层以及 judge-refiner 循环,在不重新训练底层 LLM 的前提下构建剧集级记忆并自适应地调整智能体提示词。论文还推出了 SubtitleArena 基准测试(涵盖 14 个类型、15 个目标语言区域)以及 SubMQM 评估框架,相比同类智能体系统实现了平均 6.9% 的 MQM 惩罚分数降低,并在 MuSC 基准测试上取得了最佳结果。