ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ASR+LLM打造视频课程自动摘要与知识点提取流水线

ASR+LLM打造视频课程自动摘要与知识点提取流水线 做视频课程自动摘要这件事最开始其实是被一个很现实的场景逼出来的。团队内部攒了一批技能培训视频总共上百个小时每一节都是“一个老师从头讲到尾”的形式。想找某个结论或操作步骤只能靠回忆大概在第几周的视频里然后拖进度条反复看。后来我搭了一套 ASR LLM 流水线让语音识别先把课程“变成文字”再让大模型自动生成摘要、提炼知识点效果比预期好很多。这篇文章就把整套方案从头到尾拆开讲怎么选型、怎么设计流水线、在哪一步容易踩坑以及实际跑起来要注意什么。如果你手上也有大量视频课程或会议录像需要整理或者正在做知识库自动化这篇内容应该能帮你省不少试错时间。1. 项目概述与整体思路拆解1.1 这个项目到底要解决什么问题视频课程整理这件事表面看是“把语音转成文字”但实际上可以拆成三个层次。第一层是把语音变成可检索的文本这一步是 ASR 的活第二层是在文本里提炼出重点比如这门课讲了什么、核心结论是什么这一步需要 LLM 来总结第三层是把这些重点变成结构化数据比如知识点列表、对应的时间点、关键术语表方便后续分类、检索和知识库关联。很多方案只做到第一层就停了认为有转写稿就够了。实际用下来你会发现一小时课程的逐字稿有几千行根本没人看也没有检索价值。真正的价值在于“摘要”和“知识点提取”。所以我从一开始就把 ASR 和 LLM 绑在一条流水线上而不是只做一个转写工具。这个项目适合谁参考比如负责内部培训资料整理的人、做在线课程的运营团队、想给自己收集的视频做笔记的个人开发者以及在做知识库自动化的工程师。核心目标一句话输入一个视频文件输出一份带摘要、带知识点、带时间戳的结构化笔记。1.2 为什么选 ASR LLM 这条组合路线很多人会问直接用 LLM 的多模态能力把视频喂进去不就行了理论上可行但实际工程上问题很多。一是成本多模态大模型处理一小时视频的 token 消耗远高于纯文本二是延迟直接丢长视频进去等待时间让人崩溃三是可控性语音识别、文本清洗、知识点提取每个环节独立可调出问题了能精准定位黑盒一体化反而不容易排查。另外课程类视频有很强的领域性比如编程课会出现大量英文术语、医学课有专业名词和药物名称。ASR 对这类词的识别准确率不一定高需要配合 prompt 或热词表来纠正而 LLM 在做摘要时如果转录结果里术语就错了摘要也会跟着错。所以 ASR 和 LLM 不是简单的上下游关系而是需要互相配合。我把架构分成三块ASR 转录、文本后处理、LLM 提取。每一块都可以独立测试也可以独立替换。比如后来我把 ASR 从云端服务换成了本地模型流水线其他部分完全没动这就是模块化的好处。1.3 整体流水线的数据流整套流水线的核心流程可以这样概括视频上传或指定路径后先用 ffmpeg 抽取出音频统一转成 16kHz 单声道 WAV。对长音频做切分按静音 VAD 切出有语音片段同时做相邻片段重叠避免句子被截断。将每个音频片段送入 ASR 模型带上时间戳信息转录成文本。对转录文本做清洗与段落合并去掉语气词、修正明显的口语重复恢复段落结构。将清洗后的文本按长度切片送入 LLM 分段生成摘要与知识点。把分段结果再做一次全局合并生成整节课的摘要、知识点列表和术语表。最后输出 JSON 结构落库进知识库或生成 Markdown 笔记。这套流程看起来不复杂但每一步都有不少细节。接下来就按照这条流水线把每个环节的选型、参数、坑点讲清楚。2. ASR 模块让机器先“听懂”视频课程2.1 视频音频提取与预处理这一步最简单也最容易出错。很多视频课程是录屏加人声或者会议录像音轨里除了人声还有系统提示音、键盘声。ffmpeg 是这里的第一步常用命令大概是ffmpeg -i input.mp4 -vn -ac 1 -ar 16000 -f wav output.wav-vn表示不要视频-ac 1强制单声道-ar 16000把采样率统一到 16kHz。为什么是 16kHz因为绝大多数 ASR 模型尤其是 Whisper 系列训练时用的就是 16kHz 采样高于它不会提升识别率只会增加数据量和计算量低于它则会明显掉点。另外要注意一个小时的视频抽出来的 WAV 大约 110MB 左右如果保留立体声或者原始采样率内存和带宽都会白白浪费。预处理阶段我会顺手做一个音量归一化用 ffmpeg 的 loudnorm 滤镜或者用 Python 的 pydub 处理。原因很简单如果某位讲师说话忽大忽小或者中间有一段视频素材音量特别低ASR 很容易在低音量片段产生错误转录。音量归一化后的音频识别稳定性会好很多。2.2 长音频切分策略ASR 模型对输入长度有限制即使支持长音频直接把它经一小时音频扔进去也容易出问题。Whisper 内部会做 30 秒窗口处理但如果你用官方实现跑一小时音频内存和时间都很不划算。更稳妥的做法是在流水线里先切分。我试过两种策略。第一种是固定时长切分比如每 60 秒切一刀简单粗暴但切在句子上时会破坏语义导致转录结果出现断句碎片后面 LLM 摘要质量也会受影响。第二种是基于 VAD 的静音切分也就是检测静音段在静音超过一定阈值的位置切分。推荐用 Silero VAD 或 webrtcvad速度快精度也够。我的配置是检测到超过 0.6 秒的静音就作为候选切分点然后强制每个片段最长不超过 60 秒、最短不低于 5 秒。这样既能保持句子完整又不会因为某段语音太长导致超时。还有一个关键细节切分时做重叠。我会让相邻片段重叠 3 秒转录后再用时间戳拼接。别小看这个动作它保证跨切分点的同一句话在两个片段里都完整出现拼接时取置信度高的部分能有效避免句子被拦腰截断的问题。2.3 ASR 模型选择与运行参数ASR 的选择直接影响后面所有环节值得多花点时间。我对比过三套方案方案优点缺点适合场景云端 ASR API部署简单中英文识别稳自带热词表按分钟计费隐私敏感内容不适合少量视频、对隐私不敏感Whisper 本地部署免费离线可用多语言可微调显存占用高识别速度依赖硬件有 GPU 的团队、批量处理Paraformer中文效果好速度快生态不如 Whisper 丰富定制热词较麻烦纯中文课程我最终选了 Whisper 的变体 faster-whisper因为它在保持识别率的同时推理速度比原版快三四倍。模型大小方面large-v3 对术语和口语的容错更好但如果是纯中文课程medium 级别的模型在速度与效果之间更平衡。实测下来带 GPU例如一块 3090处理一小时音频large-v3 大约耗时 10 分钟左右完全可以接受。几个值得记录的参数beam_size我习惯设 5大于 5 提升很小速度下降明显。language如果能确认课程语言强烈建议指定避免模型在开头猜错语言导致整段飘掉。initial_prompt这是 Whisper 里一个很有用的入口。我会把课程相关术语写进 prompt例如“以下是编程课程转录注意 Python、Docker、Kubernetes 等术语”能明显减少这些词的识别错误。word_timestamps开启词级时间戳后续知识点关联时间点就靠它。2.4 转录文本的后处理ASR 出来的原始文本是不能直接丢给 LLM 的。第一它没有标点或标点混乱中文尤其明显连成一大段。第二语气词非常多像“呃”“嗯”“那个”课程里几乎每隔几句就有。第三口语里经常有重复和修正比如“我们接下来讲……不对先讲另一个知识点”。我的后处理流程分三步。第一步交给一个轻量模型做标点恢复推荐用 CT-Transformer 或者直接让 LLM 加标点但只做局部修正避免大改原文。第二步用正则和词表过滤语气词但注意不要误删正常词。第三步按语义和时间戳合并段落同一主题的连续几句话说完了就合并成一段段与段之间留出空行方便后面 LLM 分辨上下文。这一步容易被忽略但其实是决定 LLM 摘要质量的重要前置环节。转录稿乱七八糟的话再好的 LLM 也提炼不出好东西。我自己的体会是宁可多花一分钟清理文本也不要让模型去猜。3. LLM 摘要与知识点提取模块3.1 Prompt 设计把任务定义清楚LLM 提取摘要和知识点本质上是一场结构化信息抽取。Prompt 写得含糊结果就含糊。我给 LLM 的任务描述一般包括四部分角色、输入内容、输出格式、约束条件。角色示例“你是一名课程编辑擅长从课堂录音转录文本中提炼内容输出简洁且信息完整的课程笔记。”输出格式我会要求 JSON比如这样的结构{ title: 课程标题, summary: 150字以内的课程摘要, knowledge_points: [ { title: 知识点标题, description: 知识点详细说明, keywords: [关键词1, 关键词2], start_time: 00:12:34, end_time: 00:18:20 } ], terms: [ {term: RAG, explanation: 检索增强生成} ] }约束条件我会写清楚摘要不要超过 N 字知识点按讲解顺序排列每个知识点必须能从原文中找到依据时间戳必须来自原文不要输出原文没有的内容。这些约束能明显减少 LLM 的幻觉和编造。3.2 分段摘要与全局合并课程转录稿动辄上万字一次塞给 LLM要么超出上下文窗口要么因为内容太长导致摘要稀释。我的处理办法是两轮提取。第一轮按信息块分段。我按转录稿的段落结构每 1500 字左右切一块有时也按按章节标题来切。每块单独丢给 LLM生成该块的小摘要和局部知识点。第二轮把各块的小摘要拼起来再做一次全局摘要。全局阶段不直接处理原始文本大大降低 token 压力也让模型更聚焦于“全局重点”。这里有个细节切块时保持上下文连续性很重要。如果切块刚好把一段话劈成两半LLM 在局部阶段就可能误解意思。我一般用滑动窗口前一块的结尾 100 字会带进后一块的开头让模型知道上下文。宁可在切分时多传几十个字也不要丢了语义连续性。3.3 知识点提取的结构化设计知识点不是简单的“列出几个重点”它需要服务于后续检索和关联。我会让 LLM 输出三种类型的结构化数据知识点、术语表、关联建议可选。知识点必须有标题、描述、关键词和时间戳。时间戳很重要用户看到“微服务拆分的原则”时最好能直接跳到视频对应位置。为了提取更准确我试过让 LLM 先读全篇再提取但 token 成本太高。后来改成“先分段提取、再全局去重合并”的策略每块提取的知识点可能会有重复和重叠全局阶段用 prompt 明确要求合并同类项、保留细节更完整的版本。这一步对最终质量影响非常大否则知识库里的知识点会又碎又重复。3.4 幻觉与质量评估的避坑思路LLM 做摘要和提取最怕的是“看起来都对实际上有编的内容”。我用了几条硬措施。第一所有关键结论必须在原文中能找到依据。我在 prompt 里要求模型先引用原文片段再输出知识点相当于给它加了一道“核查”步骤。输出里会带上一个字段evidence存放原文句子。第二时间戳只允许使用 ASR 输出的真实时间点禁止模型推断或伪造。如果发现时间戳没有对应原文位置把该条知识点的置信度标低。第三抽检机制。每个批次处理完我会随机抽 10% 的结果人工对照转录稿检查摘要是否遗漏关键结论。抽检不花太多时间但能及时发现模型在某个阶段的系统性偏差比如某节课里讲师说话特别快导致转录错误摘要也跟着错。关于模型选型我的经验是摘要和结构化提取这类任务开源模型Qwen、DeepSeek 系列已经能做得很不错不需要每次都上最强的大模型。如果追求极致稳定输出 JSON建议在 prompt 里给出完整的 JSON 示例并开启 JSON mode。4. 流水线工程化实践4.1 异步任务与状态管理ASR 和 LLM 都是耗时的计算任务绝对不能放在同步接口里。我用的是任务队列做异步处理整体流程是接收视频路径 - 创建任务记录 - 投递到队列 - 各环节 worker 消费 - 更新任务状态 - 完成后回调通知。任务状态我维护了一个简单状态机至少包含这几个状态待处理、音频处理中、ASR 识别中、文本处理中、LLM 提取中、完成、失败。每个 worker 在处理前后都会更新状态这样一旦某一步挂了可以直接根据状态定位到环节重新投递对应任务而不是整条流水线重跑。队列我选用的是 Celery 加 Redis简单可靠。如果团队已经用 RabbitMQ也可以直接用。关键是队列要能支持延迟重试和死信队列这是后面会讲到的容错基础。一个小时的视频跑完整条流水线要几十分钟中途 OOM 或超时几乎必然发生。我总结的排查顺序是先看日志在哪个环节崩溃如果是 ffmpeg 阶段多半是输入文件格式问题或音频流编码不支持如果是 ASR 阶段检查显存是否被其他进程占用如果是 LLM 阶段检查是不是某一块文本过长。4.2 容错、重试与幂等设计视频处理流水线最长可能跑几十分钟其中任何一步都可能失败。网络波动、GPU 显存不够、LLM API 限流都是家常便饭。我在这套系统里做了三层容错。第一层是超时控制。每个步骤都设置超时时间比如 whisper 推理超过 30 分钟就视为失败LLM 请求超过 60 秒就重试一次。第二层是重试策略。瞬时错误网络超时、API 限流自动重试最多三次间隔采用指数退避比如 1 秒、4 秒、16 秒。持久性错误音频文件不存在、格式损坏不重试直接进入失败状态并通知人工。第三层是幂等设计。同一任务重复执行必须得到相同结果否则重试会产出脏数据。我的做法是每个环节的输出文件带上任务 ID 作为命名前缀如果发现同名文件已存在跳过该环节数据库里的知识点记录使用唯一约束重复插入会被拒绝。4.3 成本与性能优化这条流水线真正的瓶颈不是代码而是钱和时间。LLM 调用按 token 计费如果不做优化一小时课程的转录文本可能在 1.5 万个 token 左右完整跑一遍摘要提取成本大概几块钱。如果你有大量课程要处理这个数字会迅速扩大。我常用的优化手段有三个。第一是预处理去重。转录文本里大量内容是语气词和重复表达先用规则过滤能减少 10% 到 20% 的 token。第二是合理的分块策略。分块太小每块都要交一遍重复的系统提示词浪费 token分块太大又会稀释摘要。我实践下来1500 到 2000 字是最佳区间。第三是缓存。相同视频、相同版本参数的转写结果可以缓存起来。尤其是同一门课被多次导入系统时重复 ASR 完全是浪费。我的缓存键是“视频文件哈希 模型版本 参数版本”命中缓存就不跑 ASR。GPU 方面如果 ASR 和 LLM 部署在同一台机器上注意不要让两者同时占满显存。我见过不少项目把 Whisper 和 LLM 一起怼到一张 4090 上结果两个都变慢还时不时 OOM。我的做法是按任务时段错峰调度或者在 worker 级别做好资源隔离。4.4 输出的存储与知识库集成最终的产出有两份一份是可读的 Markdown 笔记直接给人看一份是结构化的 JSON 数据给系统检索用。JSON 里包含摘要、知识点列表、术语表、时间戳我会把它落进 PostgreSQL用 JSONB 字段存整份结果同时把知识点标题和关键词建索引方便全文检索。如果要把结果接入知识库比如 Dify可以做成回调接口在流水线完成后把 JSON、源视频地址、时间戳一起推送给知识库侧的 API自动建知识文档。这里要注意知识库的切分策略和 LLM 摘要的分块策略很可能冲突一些知识库平台默认按固定长度切分会把我们精心生成的知识点拆碎。所以我会把每个知识点作为一个独立文档片段提交而不是提交整份课程笔记。5. 常见问题与排查实录5.1 ASR 识别结果质量差术语错得离谱这类问题我遇到最多。典型表现是课程里反复出现“Kubernetes”被识别成“库伯内特斯”“RAG”被识别成“拉格”。排查时先确认是单一课程问题还是所有课程都如此。如果只有特定课程出问题优先使用 initial_prompt 注入热词如果全部课程都有问题说明是模型语言或采样率的问题检查 ffmpeg 参数和 language 参数。还有一个容易被忽略的点背景音乐。有些课程会在讲师说话时垫背景音乐Whisper 会把这些内容也当成语音转录出来导致摘要里出现无关内容。我后期加了一个步骤在抽取音频时用 ffmpeg 去伴奏效果明显。5.2 LLM 摘要丢关键内容或胡乱扩展摘要丢失关键信息经常是因为输入文本太长模型在全局阶段偷懒只摘第一段的内容。解决办法是强化分段摘要在先的质量全局阶段只做基于小摘要的合并而不是让模型从头读全文。如果发现模型会扩展出原文没有的内容先检查 prompt 是否明确写了“严格基于原文不要添加原文不存在的信息”同时要求输出evidence字段。如果还是不行考虑换一个更受控的模型开 JSON mode。5.3 长视频超时、内存不足一小时的视频跑完整条流水线要几十分钟中途 OOM 或超时几乎必然发生。我总结的排查顺序是先看日志在哪个环节崩溃如果是 ffmpeg 阶段多半是输入文件格式问题或音频流编码不支持如果是 ASR 阶段检查显存是否被其他进程占用如果是 LLM 阶段检查是不是某一块文本过长。我的建议是把大视频拆得更细选择 VAD 切分后逐段处理碎片化投递到队列。这样即使某段失败重跑的代价也很小。别把整段 ASR 当做一个原子任务。5.4 时间戳对不上知识点内容时间戳错位是比较隐蔽且影响体验的问题。常见原因是 ASR 的 word_timestamps 默认参数在某些音频上偏移或者分段后拼接时重叠部分没有正确对齐。我的解决方法是在每个知识点的evidence中带上原文句子然后从 ASR 输出的词级时间戳中查找该句子的起始和结束位置而不是直接信任片段级时间戳。5.5 常见问题速查表现象可能原因处理建议专业术语识别错误模型没有热词用 initial_prompt 注入术语表背景音乐被转成文字音轨混有音乐用 ffmpeg 人声分离摘要大段缺失输入太长全局摘要偷懒强化分段摘要再合并输出 JSON 格式不稳定LLM 未开 JSON mode开启 JSON mode 并给示例ASR 阶段 OOM显存被占或音频过大缩小切分片段、错峰调度时间戳漂移重叠拼接没对齐用词级时间戳重新定位6. 一些实操体会最后聊几个我绕着弯才想明白的点。第一不要过度追求 ASR 100% 正确那是无底洞。把准确率从 90% 提到 95% 可能要用掉一半开发时间但对最终摘要和知识点的质量提升可能只有 10%。更聪明的做法是在 ASR 之后加一层文本后处理用 LLM 在摘要阶段容忍一定的转录噪声。第二流水线的价值不在于每一个模型选得多强而在于每两个环节之间衔接得多顺。后处理、缓存、重试、状态机这些“边角料”做得足够好整条流水线才算真正能跑起来。我见过不少项目模型很强但动不动就中途失败、重跑最后根本不敢放生产环境。第三把这个方案做成低成本版本也没有你想的那么难。ASR 用 faster-whisper 的 small 模型LLM 用开源模型整条链路完全可以在单张消费级显卡上跑通一小时课程的处理成本接近零。如果你只是个人用不需要追求 large 模型毕竟再好的模型落在糟糕的工程里也是白搭。这套 ASR LLM 流水线后续还能继续扩展比如加上说话人分离区分讲师和学员或者加上 OCR把课程 PPT 中的文字也纳入知识提取。这些都是下一步的事先把当前这条流水线跑稳就已经能省下大量人力成本了。
返回列表