首页
/ graphify 视频与音频转录全解析:将 Whisper 产物接入知识图谱流水线的 Step 2.5 参考实现

graphify 视频与音频转录全解析:将 Whisper 产物接入知识图谱流水线的 Step 2.5 参考实现

2026-09-07 12:43:00作者:庞眉杨Will

graphify 把"代码、文档、PDF、图片乃至视频/音频"统一映射进一张可查询的知识图谱。其中视频与音频这类无法直接读取的媒体,由 graphify-out 产物目录与 graphify.transcribe 模块负责先转录成文本、再当作普通 doc 参与语义抽取。本篇文章以仓库中随各平台 skill 分发的 graphify/skills/windows/references/transcribe.md 参考文档为骨架,结合 graphify/transcribe.pygraphify/detect.pytests/test_transcribe.py 的源码级证据,完整讲解这条 Step 2.5 转录链路的触发条件、领域提示词策略、可运行命令、环境变量契约与底层实现原理。读完你可以掌握如何在任一 coding agent 会话中把视频语料低成本地并入 graphify 图谱,也能理解 Whisper 模型选择、缓存与失败兜底的内部机制。

参考文档的角色与加载时机

这份 transcribe reference 属于 graphify skill 的按需加载片段:仅当 detect 报告了至少一个 video 文件时才读取;一个不含视频的语料库永远不会读到它。它所在的主流水线描述于各平台 skill 中,例如 graphify/skill-windows.md### Step 2.5 - Video and audio (only if video files detected) 一节:如果 detect 返回零个 video 文件,应整体跳过本步骤、直接进入 Step 3 的实体与关系抽取;若语料含视频/音频,则先按本 reference 转写为文本,再将转录稿当作 doc 文件参与 Step 3。

graphify/detect.py 可以看到分类的判定基础:FileType.VIDEO = "video",文件类型由扩展名集合决定(detect.py):

.mp4  .mov  .webm  .mkv  .avi  .m4v   # 视频
.mp3  .wav  .m4a   .ogg                # 音频

值得注意,这份集合在 graphify/transcribe.py 中按同一字面量维护,并在 detect 落盘的结果(graphify-out/.graphify_detect.json)里以 files.video 数组形式暴露给后续步骤——这正是本步骤命令的输入来源。此外 README 的隐私一节明确说明:视频/音频在本地用 faster-whisper 转录,数据不离开机器

为什么必须先转写:媒体 → 文本 → doc 的降级策略

视频与音频文件无法被直接解析成实体与关系。参考文档给出的处理范式是:

  1. 先转录为纯文本;
  2. 把转录稿当作与 .md/.txt 同等的 doc 文件,交回 Step 3 的语义子代理做知识抽取。

也就是说,Step 2.5 是一个"文本化预处理层",它让 graphify 的语义抽取对媒体输入透明。这一设计也解释了 graphify/skill-windows.md 中 Step 3 对文件类别的说明:语义抽取只针对 documentpaperimage 展开,视频必须先经本步骤转换为文档。

Step 1:用语料自身充当提示词来源,写出 Whisper 初始提示

参考文档的核心巧思在于:不再额外调用一次 LLM API。执行转录的 coding agent(Claude Code、Codex、Gemini CLI 等)本身就是语言模型,可以直接从 detect 结果或历史分析文件中读取顶层 god node 标签,自行"脑补"出一句领域提示(domain hint),再把它作为 initial_prompt 喂给 Whisper。

文档给出的两个示例:

  • 标签 transformer, attention, encoder, decoder"Machine learning research on transformer architectures and attention mechanisms. Use proper punctuation and paragraph breaks."
  • 标签 kubernetes, deployment, pod, helm"DevOps discussion about Kubernetes deployments and Helm charts. Use proper punctuation and paragraph breaks."

特例:若语料只有视频文件、没有任何其他 doc/代码(无 god node 可用),则使用通用兜底提示词:

Use proper punctuation and paragraph breaks.

环境变量契约:GRAPHIFY_WHISPER_PROMPT 必须 export

写好的领域提示句必须导出为 GRAPHIFY_WHISPER_PROMPT(这是转录器读取的精确名称),并且在 bash 里必须使用 export 而不是简单赋值,否则子进程 Python 看不到该变量。文档强调这一步不能省。

graphify/transcribe.py 中,这一环境变量约定在 build_whisper_prompt()transcribe.py)中得到印证:它优先读取 os.environ.get("GRAPHIFY_WHISPER_PROMPT") 作为 override,随后才退回到由 god node label 拼接的模板 "Technical discussion about <topics>. Use proper punctuation and paragraph breaks."。测试 tests/test_transcribe.pytest_build_whisper_prompt_env_override 专门验证了环境变量可短路程序化拼接;test_build_whisper_prompt_no_nodestest_build_whisper_prompt_nodes_without_labels 则保证空输入或缺 label 键的节点不会导致异常。

Step 2:运行转录并落盘路径清单

参考文档给出如下 bash 命令块(注意其中蕴含三条关键约定):

export GRAPHIFY_WHISPER_MODEL=base  # or whatever --whisper-model the user passed (must be exported)
export GRAPHIFY_WHISPER_PROMPT="<the one-sentence domain hint you composed in Step 1>"
$(cat graphify-out/.graphify_python) -c "
import json, os, sys
from pathlib import Path
from graphify.transcribe import transcribe_all

detect = json.loads(Path('graphify-out/.graphify_detect.json').read_text(encoding=\"utf-8\"))
video_files = detect.get('files', {}).get('video', [])
prompt = os.environ.get('GRAPHIFY_WHISPER_PROMPT', 'Use proper punctuation and paragraph breaks.')

transcript_paths = transcribe_all(video_files, initial_prompt=prompt)
# Write the JSON from Python (NOT a shell '>' redirect): transcribe_all/Whisper
# print progress to stdout, which would otherwise corrupt the JSON file (#1392).
Path('graphify-out/.graphify_transcripts.json').write_text(json.dumps(transcript_paths, ensure_ascii=False), encoding=\"utf-8\")
print(f'Transcribed {len(transcript_paths)} file(s)', file=sys.stderr)
"

对这三条约定的逐条解读:

  1. 解释器间接寻址 $(cat graphify-out/.graphify_python):skill 流水线在 Step 1 会把真正装有 graphify 的 Python 解释器路径写入 graphify-out/.graphify_python,随后的每个 Python 步骤都必须经它执行,保证所用解释器确实能 import graphify。参见 graphify/skill-windows.md 的解释器约定;该文件还记录了一个 Windows 特有的细节——写 .graphify_python 时必须用无 BOM 的 UTF-8(WriteAllText),避免 BOM 混入路径导致构建失败。

  2. JSON 必须由 Python 写盘,禁用 shell > 重定向transcribe_all 与底层 Whisper 会把进度信息打印到 stdout,若再用 shell 重定向落盘,进度噪声会污染 JSON 文件(文档内标注的问题编号 #1392)。因此示例将进度打印显式送到 sys.stderr,路径清单则用 Path.write_text() 写为 graphify-out/.graphify_transcripts.jsonensure_ascii=False 保证非 ASCII 路径不被打乱)。

  3. transcribe_all 的入参即 initial_prompt:领域提示只构造一次,对该批全部文件共享。

转录完成后的收尾动作

按参考文档,转录结束后必须依次执行:

  • graphify-out/.graphify_transcripts.json 读取转录稿路径;
  • 在向 Step 3B 派发语义子代理之前,把这些路径追加进 docs 列表
  • 打印创建数量:Transcribed N video file(s) -> treating as docs
  • 单个文件转录失败时打印 warning 并继续处理其余文件,而不是中止整个流水线。

"失败不中断"在源码中是显式保证的:transcribe_all()transcribe.py)对每个文件包一层 try/except,失败时打印 warning: could not transcribe {vf}: {exc} 后继续;tests/test_transcribe.pytest_transcribe_all_skips_failed 用 mock 抛错验证了失败文件会被跳过且返回列表为空。

Whisper 模型选择与运行环境前提

参考文档明确了模型契约:

  • 默认模型为 base;若用户传了 --whisper-model <name>,则必须 export GRAPHIFY_WHISPER_MODEL=<name> 后再执行上述命令。
  • 各平台 skill 的用法示例中均有对应 CLI 说明,例如 /graphify <path> --whisper-model medium 表示"用更大的 Whisper 模型换取更高转录准确率"。

graphify/transcribe.py_DEFAULT_MODEL = "base"_model_name() 实现了同一契约:读 GRAPHIFY_WHISPER_MODEL,缺省回落到 base。模型加载与推理参数集中在 transcribe()transcribe.py):

model = WhisperModel(model_name, device="cpu", compute_type="int8")
segments, info = model.transcribe(
    str(audio_path),
    beam_size=5,
    initial_prompt=prompt,
)

即使用 faster-whisperWhisperModel,默认 CPU + int8 量化运行、beam_size=5initial_prompt 传入领域提示;转录文本按非空 segment 分行拼装后写入 graphify-out/transcripts/<音频文件stem>.txt(输出目录由 out_path("transcripts") 决定,见 transcribe.py,其中 out_path 封装了默认输出目录 graphify-out,可被 GRAPHIFY_OUT 环境变量整体覆盖,参见 graphify/paths.py)。模块头部注释也点明:转录产物随后进入图谱抽取流程。

两个额外的重要机制:

  • 依赖提示_get_whisper() 在缺少 faster_whisper 时抛出明确错误,提示执行 pip install 'graphifyy[video]'。README 的 extras 表把 video 能力对应为 faster-whisper + yt-dlp,安装方式为 uv tool install "graphifyy[video]"
  • 缓存与强制重转写transcribe() 若发现同名 .txt 已存在且未传 force=True,直接返回缓存路径,不重复运行 Whisper。这一点由 tests/test_transcribe.pytest_transcribe_uses_cachetest_transcribe_force_reruns 双重验证,是增量运行节省时间/算力的基础。

扩展能力:URL 输入与安全防线(源码佐证)

参考文档正文面向"本地 video 文件清单",而 graphify/transcribe.py 提供的实现能力略超于此,可作为理解后续行为的背景:is_url() 依据 http://https://www. 前缀识别 URL;download_audio()yt-dlp 拉取纯音频流,并用 URL 的 SHA-1 前 12 位生成稳定的 yt_<hash>.<ext> 缓存名,避免以视频标题作文件名带来的长度与字符风险。README 的用法示例中 /graphify add <video-url> 即对应"转录并加入一个视频"的场景。

值得强调的安全设计:download_audio() 在执行 yt-dlp 之前会调用 graphify.security.validate_url(),用于拦截私网 IP 与非法 scheme(见 transcribe.py)。这是语料可能来自共享/克隆文件夹时的纵深防御。

平台差异说明:为何这份 reference 挂在 "windows" 下却全文通用

本参考文档的生成副本位于 tools/skillgen/expected/graphify__skills__windows__references__transcribe.md,其内容与源码副本一致。从仓库结构看,references/transcribe.mdwindowsagentsclaudecodex 等各平台 skill 目录下逐字复刻,说明该步骤的领域逻辑是平台无关的——真正的平台差异只体现在调用外壳上:POSIX 风格 skill 用 export$(cat ...),而 graphify/skill-windows.md 采用 PowerShell 的 & (Get-Content graphify-out\.graphify_python) 直呼保存的解释器。若在 PowerShell 主机上执行本步骤,可将两条 export 等价改写为 $env:GRAPHIFY_WHISPER_MODEL = "base"$env:GRAPHIFY_WHISPER_PROMPT = "<domain hint>",使子进程 Python 同样能读到这两个变量,再以相同的方式读取 .graphify_detect.json、调用 transcribe_all 并写盘 .graphify_transcripts.json

参考文档在仓库中的血缘与回归保障

tools/skillgen/expected/ 下保存着每次 skill 生成的期望快照(golden),tools/skillgen/expected/graphify__skills__windows__references__transcribe.md 即本 reference 的回归基准,防止生成器漂移。与该文档对应的实现侧保障链条可沿三条线索展开阅读:

  • 语义与提示词逻辑:graphify/transcribe.pybuild_whisper_prompttranscribetranscribe_alldownload_audio);
  • 检测与分类契约:graphify/detect.pyFileType.VIDEOVIDEO_EXTENSIONS,以及 README 对 video extra、隐私承诺与 /graphify <video-url> 用法的说明;
  • 行为契约:tests/test_transcribe.py(缓存命中、force 重转写、缺依赖抛错、空输入安全、批量失败跳过、环境变量 override 等)。

简言之,Step 2.5 是 graphify 把"不可读媒体"纳入统一知识图谱的桥梁:detect 负责发现,agent 负责用 god node 标签生成零额外 API 成本的领域提示,graphify.transcribe 负责以本地 faster-whisper 完成转录、缓存与失败隔离,最终转录稿作为 doc 回流 Step 3,与代码、PDF、图片一起沉淀为可查询的图谱节点。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388