端到端的视频翻译自动化流水线。从 YouTube / 本地文件 / HTTP 直链下载/导入视频,经语音识别、智能断句、LLM 翻译、字幕嵌入,直至上传 B 站,全流程自动完成。
支持 命令行(CLI) 和 Web 管理界面 两种使用方式。CLI 是核心能力载体,WebUI 是增强管理层——类似 Clash 与其 Dashboard 的关系:所有处理能力完全不依赖 WebUI,WebUI 仅提供可视化操作的便利。
B 站上有使用 VAT 翻译的视频实例(日语 VTuber → 中文字幕),可直接查看翻译效果:
- 白上吹雪 | 试吃测评 — 闲聊类,纯对话场景
- 白上吹雪 | 皇牌空战7 — 游戏实况,解说+操作
- 白上吹雪 | 马里奥赛车 — 短视频,高密度对话
更多翻译视频见 B 站空间(158+ 视频)。
⚠️ VAT 主要在 Linux 多 GPU 服务器(Ubuntu 22.04, CUDA 12.x, 多张 RTX 4090)上开发和测试。如果你在 Windows 家用电脑上运行,可能遇到以下问题:
- CUDA / FFmpeg / yt-dlp 的路径和环境变量差异
- 多 GPU 调度相关功能未在 Windows 上测试
- 部分依赖(如 faster-whisper)在 Windows 上的安装可能需要额外步骤
欢迎反馈 Windows 环境下的兼容性问题。
VAT 的设计目标是服务器端批量视频翻译,而非面向单个视频的桌面工具。
- CLI 是核心:所有处理能力通过
vat命令行暴露,可脚本化、可集成到其他系统 - WebUI 是增强:WebUI 通过调用 CLI 子进程执行任务,不引入额外依赖。即使 WebUI 不启动,系统能力不受任何影响;WebUI 提供的是视频信息浏览、批量选择、进度可视化等便利
- 流水线可拆分:7 个阶段独立可控,可以只跑其中几步、跳过已完成的、或强制重跑某一步。中断后从断点继续
- 可集成:pipeline 模块可以直接被其他 Python 项目导入使用,不绑定任何 UI 框架
- 批量管理:支持 Playlist 级别的增量同步、按时间排序、批量处理,管理数千个视频
- 阶段级追踪:每个视频的每个处理阶段独立记录状态,支持断点续传和选择性重跑
- 并发调度:多 GPU 任务调度、多视频并行处理
- 状态可恢复:进程崩溃后自动检测孤儿任务,重启即可继续
- Watch 模式:自动监控 YouTube Playlist,发现新视频后自动提交全流程处理任务(详见 Watch Mode 文档)
- 跨进程资源锁:多个 VAT 进程并发运行时,自动协调 YouTube 下载和 B站上传的速率,防止限流/风控
YouTube URL / Bilibili URL / HTTP 直链 / 本地文件
│
├─ 1. Download ─── 下载/导入视频 + 字幕 + 元数据 + 场景识别 + 视频信息翻译
├─ 2. Whisper ──── faster-whisper 语音识别(支持分块并发、人声分离)
├─ 3. Split ────── LLM 智能断句(零碎片段→完整句子,时间戳对齐)
├─ 4. Optimize ─── LLM 字幕优化(纠错、术语统一)
├─ 5. Translate ── LLM 反思翻译(初译→反思→重译)
├─ 6. Embed ────── 字幕嵌入视频(硬字幕 GPU 加速 / 软字幕)
└─ 7. Upload ───── 自动上传 B 站(标题模板、封面、分区推荐)
基于 faster-whisper,在实际使用中对参数做了较广泛的测试(参见 ASR 评估报告),采用了针对日语口语场景(VTuber 直播、游戏实况等)调优后的配置。
- 分块并发:长视频自动切分为多段并行转录,合并时处理重叠区域
- 词级时间戳,为后续断句提供精确定位
- ASR 后处理:幻觉检测(移除重复片段、无意义的固定短语等)、日语标点标准化。后处理实现参考了 WhisperJAV 项目
- 人声分离(可选,默认未启用):基于 Mel-Band-Roformer 模型,用于处理有背景音乐的视频
Whisper 输出的片段通常零碎且不完整。本阶段使用 LLM 将这些片段重组为符合人类阅读习惯的完整句子。
断句的基本思路借鉴自 VideoCaptioner 项目,但在时间戳对齐算法上做了较大改动——原实现在长视频上容易出现时间漂移和句子时间不对齐的问题,当前版本在对齐精度上有明显改善。
- 支持分块断句(长视频)和全文断句(短视频)
- 可配置的句子长度约束(CJK / 英文分别控制)
- 场景感知:不同类型的视频(游戏、闲聊、歌曲等)使用不同的断句策略
翻译引擎的核心实现参考自 VideoCaptioner 项目,包括:
- 反思翻译:初译 → 反思 → 重译,显著提升翻译质量
- 字幕优化:翻译前自动修正原文中的错别字、统一术语
- 场景提示词:根据视频类型(游戏、科普、闲聊等)自动加载专用提示词
- 自定义提示词:支持为特定频道或内容定制翻译/优化提示词
VAT 在此基础上的改动:
- 上下文关联处理:批量翻译时支持分 chunk 顺序执行并维护前文上下文(而非纯并行),以保持术语和风格一致性
- 更灵活的模型配置(支持不同阶段使用不同 LLM 服务商,当前生产配置:断句 gpt-4o-mini / 优化 kimi-k2.5 / 翻译 gemini-3-flash)
关于本地模型:配置中支持填写本地 LLM 地址(如 Ollama),但目前未做专门适配和测试,实际效果未验证。如果需要在本项目中自动唤起本地服务(类似 GalTransl),尚未实现。主要是因为 gpt-4o-mini 的能力已经不足了,gpt-5-nano 才勉强可用——本地模型达到这个性能目前仍很困难
- 硬字幕:GPU 加速(H.264/H.265/AV1),封装了 FFmpeg 的 NVIDIA 硬件编码调用
- 软字幕:快速封装,保持原画质
- 内置多套 ASS 字幕样式模板(默认、科普风、番剧风、竖屏等),并根据视频分辨率自动缩放
基于 yt-dlp:
- 支持 YouTube 视频和播放列表
- 自动下载人工字幕(检测到人工字幕时可跳过 ASR)
- Playlist 增量同步:按时间顺序管理视频,支持后续只同步新增视频
- LLM 场景自动识别(游戏、闲聊、歌曲、科普等)
- LLM 视频信息自动翻译(标题、简介、标签),翻译后自动进行译名标准化(港台用语→大陆标准,如"マリオ"→"马里奥"而非"马力欧")
- 直播视频处理:三阶段策略(尝试
live_from_start从头下载 → 等待直播结束 → VOD 下载),对上层流水线透明 - Upcoming 视频:支持提交尚未发布的视频任务,download 阶段自动轮询等待视频发布后再下载
基于 biliup:
- 模板系统:标题/简介支持变量替换(频道名、翻译标题等)
- 自动获取封面、生成标签
- LLM 推荐 B 站分区
- 支持添加到合集(上传后自动添加到指定的 B站新版合集/SEASON),支持合集标题同步(用实际视频标题替换合集中的默认名称)
- 定时上传:支持 cron 表达式指定上传时间,可配置每次触发上传的视频数量(
--upload-batch-size),支持两种模式:- cron 模式(默认):后台进程等待 cron 触发后上传
- dtime 模式:立即全部上传,通过 B站定时发布 API 指定发布时间(需 >2h,无需后台进程)
- 多 GPU 任务调度:自动检测显卡,分配视频到不同 GPU
- 步骤级状态追踪:每个阶段独立记录状态,支持断点续传
- 配置快照缓存:修改断句参数只重跑断句,不重跑 ASR
- 多视频并行处理(可配置并发数)
Pipeline 对处理过程中的异常采用三级分类:
| 级别 | 行为 | 适用场景 |
|---|---|---|
| 致命 | 阶段标记 FAILED,中止后续步骤 | 翻译片段失败(任何一条)、API 配置错误(认证/地区限制等) |
| 警告 | 继续执行,视频标记 ⚠ | 优化阶段少量批次失败(网络抖动级别)、ASR 崩溃片段被移除、合集添加失败 |
| 正常 | 仅记录日志 | ASR 静默间隙检测(直播间正常现象) |
核心原则:
- 翻译零容忍:翻译结果不允许有任何片段缺失。批量翻译失败会降级到单条翻译重试,但任何一条翻译失败都会导致整个阶段 FAILED。宁可让用户重跑,也不让缺失的翻译混入最终结果
- 优化容忍网络抖动:优化阶段容忍少量失败(不超过 max(2, 总批次数×5%)),失败的批次保留原文。超过阈值则判定为系统性问题,整体 FAILED
- 不可重试错误 fail-fast:API 认证失败、地区限制等配置错误不会重试,直接 FAILED
- 非致命问题可追溯:警告级别的问题写入数据库
processing_notes字段,在 Web UI 视频详情页以 ⚠ 标识展示,用户无需翻阅日志即可发现
- Python 3.10+
- CUDA GPU(推荐,ASR 和硬字幕嵌入需要)
- ffmpeg(系统级安装)
- LLM API(断句、翻译、优化需要;支持任何 OpenAI 格式 API)
git clone <repo-url> && cd vat
pip install -r requirements.txt
pip install -e .关于
vat命令与python -m vat:安装后可直接使用vat命令。如果vat命令不可用(PATH 问题或开发模式迭代频繁),可用python -m vat替代,两者等价。本文档示例以vat为主,均可替换为python -m vat。
字体文件(备用):
将字体放入 vat/resources/fonts/ 目录。大部分 Ubuntu 系统已自带我们默认样式使用的 NotoSansCJK,通常无需手动安装。
| 字体 | 用途 | 来源 |
|---|---|---|
| NotoSansCJKsc-VF.ttf | 默认中日韩字体 | Google Fonts |
# 设置 LLM API Key(环境变量)
export VAT_LLM_APIKEY="your-api-key"
# 生成配置文件
vat init
# 编辑配置(路径、模型、翻译参数等)
nano config/config.yaml关键配置项:
| 配置项 | 说明 |
|---|---|
storage.work_dir |
工作目录(处理中间文件) |
storage.output_dir |
输出根目录(每个视频的输出路径 = output_dir/video_id,运行时计算,不存储在数据库中) |
storage.models_dir |
模型文件目录 |
asr.model |
Whisper 模型(推荐 large-v3) |
asr.language |
源语言(如 ja) |
llm.api_key |
全局 LLM API Key(支持 ${ENV_VAR} 引用环境变量) |
llm.base_url |
全局 LLM API 地址 |
translator.llm.model |
翻译使用的 LLM 模型 |
translator.llm.enable_reflect |
是否启用反思翻译 |
各阶段(断句、翻译、优化)支持独立覆写 api_key / base_url / model,留空则继承全局配置。
代理同样支持分阶段覆盖:proxy.http_proxy 为全局默认,可通过 proxy.llm、proxy.translate、proxy.downloader 等为各环节指定独立代理。LLM 环节的 fallback 链为:环节专属 → proxy.llm → proxy.http_proxy。
完整说明参见 config/default.yaml 中的注释。
# 处理 YouTube 视频(全流程:下载→识别→断句→优化→翻译→嵌入)
vat pipeline --url "https://www.youtube.com/watch?v=VIDEO_ID"
# 处理本地视频文件
vat pipeline --url "/path/to/video.mp4"
# 处理 HTTP 直链视频
vat pipeline --url "https://example.com/video.mp4"
# 手动指定标题(本地/直链视频推荐)
vat pipeline --url "/path/to/video.mp4" --title "我的视频标题"
# 处理 YouTube 播放列表
vat pipeline --playlist "https://www.youtube.com/playlist?list=PLAYLIST_ID"
# 多 GPU 并行
vat pipeline --url "URL" --gpus 0,1# 方式一:指定阶段列表(逗号分隔)
vat process -v VIDEO_ID -s download,whisper,split
# 方式二:指定单个阶段
vat process -v VIDEO_ID -s translate
# 方式三:使用快捷命令
vat download -u URL # 仅下载
vat asr -v VIDEO_ID # 仅语音识别
vat translate -v VIDEO_ID # 仅翻译
vat embed -v VIDEO_ID # 仅嵌入字幕
# 强制重跑(忽略已完成状态)
vat process -v VIDEO_ID -s translate -f
# 指定 GPU
vat process -v VIDEO_ID -s whisper -g cuda:1
# 多视频并行
vat process -v VID1 -v VID2 -v VID3 -s download,whisper -c 3
# 遇到失败立即停止(不处理后续视频)
vat process -p PLAYLIST_ID -s all --fail-fast阶段跳跃:如果指定了不连续的阶段(如
whisper,embed以测试日语原文嵌入效果),系统会自动填充中间阶段并以“直通模式”执行(复制输入到输出),直通阶段标记为SKIPPED。
# 同步播放列表
vat playlist sync "https://www.youtube.com/playlist?list=PLAYLIST_ID"
# 查看处理状态
vat statusWatch 模式是 VAT 的全自动运行方式:持续监控指定的 YouTube Playlist,发现新视频后自动完成「下载→识别→断句→优化→翻译→嵌入→上传→添加合集」全流程,无需人工干预。适用于需要时效性的场景(如 VTuber 直播结束后自动翻译上传)。
# 持续监控 Playlist(默认每 60 分钟检查一次)
vat watch -p PLAYLIST_ID
# 同时监控多个 Playlist,自定义间隔
vat watch -p PL_FUBUKI -p PL_MARINE --interval 30
# 单次检查后退出(可搭配系统 cron)
vat watch -p PLAYLIST_ID --once
# 指定 GPU 和并发数
vat watch -p PLAYLIST_ID --gpu cuda:0 --concurrency 2工作原理:
- Watch 进程只负责发现新视频并提交任务,实际处理由 JobManager 子进程完成(复用
vat process基础设施) - 内置跨进程资源锁:多个 VAT 进程(watch 自动提交 + 用户手动执行)同时运行时,自动协调 YouTube 下载和 B站上传的速率,防止限流/风控
- 每轮检查自动过滤已处理、正在处理、不可用的视频,避免重复提交
- 失败的视频在后续轮次自动重试(同一视频最多重试 3 次)
- 支持通过 WebUI 的 Watch 管理页面启动/停止/查看状态
详细设计参见 Watch Mode 文档。
| 命令 | 说明 |
|---|---|
vat pipeline -u URL |
完整流水线(下载到嵌入) |
vat process -v ID -s STAGES |
细粒度阶段控制 |
vat download -u URL |
仅下载 |
vat asr -v ID |
仅语音识别 |
vat translate -v ID |
仅翻译 |
vat embed -v ID |
仅嵌入字幕 |
vat upload video VIDEO_ID |
上传到 B 站 |
vat upload playlist PLAYLIST_ID |
批量上传播放列表 |
vat upload sync -p PLAYLIST_ID |
合集同步(添加+排序) |
vat upload update-info -p PLAYLIST_ID |
批量更新B站视频标题/简介 |
vat upload sync-db -s SEASON -p PLAYLIST |
同步B站合集信息回数据库 |
vat process -v ID -s upload --upload-cron "0 12,18 * * *" |
定时上传(每天 12/18 点,默认每次 1 个) |
vat process -p PL -s upload --upload-cron "0 12 * * *" --upload-batch-size 3 |
定时上传,每次 3 个 |
vat process -p PL -s upload --upload-cron "0 12 * * *" --upload-mode dtime |
B站定时发布模式 |
vat playlist sync URL |
同步播放列表 |
vat playlist refresh ID |
刷新视频信息(补全缺失的封面、时长等) |
vat status |
查看处理状态 |
vat clean -v ID |
清理中间产物 |
vat clean -v ID --records |
清理产物+删除记录 |
vat bilibili login |
B 站登录获取 Cookie |
vat bilibili rejected |
列出被退回的稿件及违规详情 |
vat bilibili fix --aid AID |
单次修复被退回稿件(累积式遮罩,优先本地文件,降级从B站下载) |
vat tools fix-violation --aid AID |
自动循环修复:mask→上传→等待审核→check→重试(默认10轮,等待=上传耗时×3,下限15分钟),通过后自动从DB模板重新渲染元信息并添加到合集 |
vat tools sync-playlist --playlist ID |
同步 YouTube Playlist(增量更新) |
vat tools refresh-playlist --playlist ID |
刷新 Playlist 视频信息 |
vat tools retranslate-playlist --playlist ID |
重新翻译 Playlist 视频标题/简介 |
vat tools upload-sync --playlist ID |
批量添加视频到B站合集 |
vat tools update-info --playlist ID |
批量更新已上传视频的标题和简介 |
vat tools sync-db --season S --playlist ID |
从B站合集同步信息回数据库 |
vat tools season-sync --playlist ID |
合集同步(添加+排序) |
vat watch -p PLAYLIST_ID |
自动监控 Playlist 并处理新视频(持续运行) |
vat watch -p PL1 -p PL2 -i 30 |
同时监控多个 Playlist,30 分钟间隔 |
vat watch -p PLAYLIST_ID --once |
单次检查后退出(可搭配系统 cron) |
vat tools子命令与原有 CLI 命令功能相同,区别在于输出标准化进度标记([N%]/[SUCCESS]/[FAILED]),可被 WebUI 的 JobManager 作为子进程调度和监控。
data/videos/<VIDEO_ID>/
├── <video>.mp4 # 原始下载视频
├── original_raw.srt # Whisper 原始转录
├── original.srt # 断句后的原文字幕
├── optimized.srt # 优化后的原文字幕
├── translated.srt # 翻译后的字幕
├── translated.ass # ASS 格式字幕(带样式)
└── final.mp4 # 嵌入字幕的最终视频
WebUI 是对 CLI 能力的可视化封装。所有任务通过子进程调用 CLI 执行,与 Web 服务器生命周期完全解耦——Web 服务重启不影响正在运行的任务。
# 启动(默认端口 8094)
vat web
# 或指定端口
vat web --port 8080视频列表页提供全局总览:状态统计、搜索筛选(按标题/频道/状态/阶段/Playlist)、分页浏览。每个视频显示缩略图、来源、时长、7 阶段状态、进度、发布日期。
视频详情页展示完整的处理时间线、翻译信息、相关文件(支持在线查看、编辑字幕、播放视频)。可直接点击执行某个阶段或强制重做。
支持添加 YouTube Playlist 并增量同步。视频按发布日期排序,支持批量处理、范围选择。每个 Playlist 可独立配置翻译/优化提示词和 B 站上传参数。
创建任务时可选择视频、执行阶段、GPU 设备、并发数。任务执行中提供实时日志(SSE 推送)和进度追踪。支持取消、重试、批量删除。
可以控制定时任务
独立的 Watch 管理页面,统一管理所有自动监控会话。可直接在 WebUI 中启动/停止 Watch 任务,查看每轮检查的发现视频数、提交任务数、错误信息等实时状态。Playlist 详情页也提供快捷的「开始监控」入口。
WebUI 内置 SQLite 数据库只读浏览器(/database),可直接查看所有数据表的结构和内容,支持分页、搜索、排序、JSON 字段展开。用于开发调试和数据检查。
详细操作说明参见 WebUI 使用手册。
vat/
├── asr/ # 语音识别模块(Whisper + LLM 断句)
│ ├── whisper_wrapper.py # faster-whisper 封装
│ ├── chunked_asr.py # 分块并发 ASR
│ ├── split.py # LLM 智能断句
│ ├── postprocessing.py # 后处理(幻觉/重复检测)
│ └── vocal_separation/ # 人声分离
├── translator/ # 翻译模块
│ └── llm_translator.py # LLM 反思翻译引擎
├── llm/ # LLM 基础设施
│ ├── client.py # 统一 LLM 调用客户端(多端点、缓存、重试)
│ ├── scene_identifier.py # 场景识别
│ ├── video_info_translator.py # 视频信息翻译(标题/简介/标签 + B站分区推荐)
│ └── prompts/ # 提示词管理(Markdown 文件 + 模板变量)
├── embedder/ # 字幕嵌入模块
│ └── ffmpeg_wrapper.py # FFmpeg 封装(软/硬字幕 + GPU 加速)
├── downloaders/ # 下载器(多源支持)
│ ├── base.py # BaseDownloader / PlatformDownloader 两层接口
│ ├── youtube.py # YouTube 下载器(yt-dlp)
│ ├── local.py # 本地文件导入器(软链接 + ffprobe)
│ └── direct_url.py # HTTP/HTTPS 直链下载器
├── uploaders/ # 上传器(B 站 biliup + 模板渲染 + 合集管理)
├── pipeline/ # 流水线编排
│ ├── executor.py # VideoProcessor(阶段调度)
│ ├── scheduler.py # 多 GPU 调度器
│ └── progress.py # 进度追踪
├── web/ # Web 管理界面(FastAPI + Jinja2)
│ ├── app.py # 应用入口 + 页面路由
│ ├── jobs.py # 任务管理器(子进程调度 + SQLite 持久化)
│ ├── routes/ # API 路由(视频/Playlist/任务/B站/提示词/Watch/数据库)
│ └── templates/ # Jinja2 + TailwindCSS 页面模板
├── cli/ # CLI 命令(click)
├── services/ # 业务逻辑层(Playlist 同步/Watch 服务/元信息管理)
├── subtitle_utils/ # 字幕工具(文本对齐、格式定义)
├── utils/ # 通用工具(GPU 管理、日志、缓存、输出验证、跨进程资源锁)
├── database.py # SQLite 数据层(WAL 模式)
├── config.py # 配置管理(YAML + 环境变量)
└── models.py # 数据模型定义
其中每个模块文件夹内均有各自的文档说明
在 vat/llm/prompts/custom/ 下创建提示词文件,在配置中引用文件名:
translator:
llm:
custom_prompt: "my_channel" # 翻译提示词
optimize:
custom_prompt: "my_channel" # 优化提示词也可通过 WebUI 的 Prompts 管理页面创建和编辑。提示词编写指南参见 提示词优化指南。
VAT 根据视频标题和简介自动识别场景类型(游戏、闲聊、歌曲、科普等),并加载对应的场景提示词。场景配置定义在 vat/llm/scenes.yaml 中。
不同类型的视频可能需要不同的 ASR 参数:
- 游戏/直播:关闭 VAD,降低
no_speech_threshold - 纯人声(播客):开启 VAD
- 背景音乐重的视频:考虑启用人声分离
参数详解参见 ASR 评估报告。
多 GPU 环境下的任务分配策略说明参见 GPU 分配规范。
| 文档 | 内容 |
|---|---|
| ASR 评估报告 | Whisper 参数评估实验(350 个 VTuber 视频) |
| 翻译与 ASR 综合评测 | 国产/海外 LLM 翻译对比、ASR 增强实验 |
| 提示词优化指南 | 翻译/优化提示词的编写方法 |
| GPU 分配规范 | 多 GPU 调度策略 |
| WebUI 手册 | Web 界面功能详解与操作说明 |
| YouTube 字幕 | YouTube 人工字幕检测与使用 |
| 字幕样式指南 | ASS 字幕样式模板说明 |
| 多源下载设计 | 本地文件/直链/YouTube 多源下载架构设计 |
| 已知问题 | 已知限制与 LLM 成本参考 |
| Watch Mode 文档 | Watch 模式设计与实现 |
| ASR 增强实验 | 空 chunk 重试、分块参数调优等实验记录 |
如果你对图结构与 Transformer 架构的结合感兴趣,欢迎查看我们的另一项研究工作:
Graph Tokenization for Bridging Graphs and Transformers
探索如何将图结构数据有效转换为 Transformer 可处理的 token 序列。
本项目集成了以下开源项目的内容,或进行了二次封装调用:
- VideoCaptioner — 分块 ASR、智能断句、反思翻译、ASS 渲染的核心参考。VAT 的断句和翻译模块在此基础上做了修改和扩展
- GalTransl — 想法来源
- faster-whisper — 语音识别
- yt-dlp — 视频下载
- biliup — B 站上传
- Mel-Band-Roformer — 人声分离模型
- WhisperJAV — ASR 后处理参考(幻觉检测、重复清理)
详细致谢信息参见 acknowledgement.md。
如果觉得项目有用,欢迎请我喝杯咖啡:
GPLv3










