您的位置:首页 > 手游攻略 > Qwen ASR 1.7B 实战:把本地语音识别接入熙瑾会悟:搭建私有化 AI 会议助手

Qwen ASR 1.7B 实战:把本地语音识别接入熙瑾会悟:搭建私有化 AI 会议助手

作者:互联网  时间: 2026-07-13 09:10:07  

Qwen ASR 1.7B 实战:把本地语音识别接入熙瑾会悟,搭建私有化 AI 会议助手

{"type":"doc","content":[{"type":"heading","attrs":{"id":"36dfc9c2-a256-46e7-a14a-0ff59e3c4a73","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"一、引言:会议转写不难,难的是把它接进真实业务流程"}]},{"type":"paragraph","attrs":{"id":"342df0d3-c7ab-4379-a5ef-cb7fe25aea2b","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"很多人第一次做会议录音转写时,通常会从 ASR 模型开始:准备一段音频,调用模型,得到一段文字。这个过程用于技术验证没有问题,但如果要进入真实会议场景,问题会很快变复杂。"}]},{"type":"paragraph","attrs":{"id":"281c37e3-1b17-4cfd-9af3-9c8de21bf934","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"真实会议通常不是一段干净的测试音频。"}]},{"type":"paragraph","attrs":{"id":"f1f1b003-6428-436b-abc8-b1d9c47b03b9","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"它可能持续 30 分钟、1 小时甚至更久;可能包含多人发言、插话、远距离拾音、环境噪声;也可能出现大量专业术语、英文缩写、项目代号和组织内部简称。"}]},{"type":"paragraph","attrs":{"id":"eb77fb55-30a8-4331-aa2c-151d7e2ded4b","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"更重要的是,用户最终需要的通常不是一段原始转写稿,而是一份可以阅读、复核、检索、归档的会议资料。"}]},{"type":"paragraph","attrs":{"id":"ff5ed224-2593-42cb-aecf-1fc734920d7b","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"因此,会议转写系统不能只停留在“音频转文字”这一层,而需要形成完整链路:"}]},{"type":"codeBlock","attrs":{"id":"494bffe2-a10c-49ab-8368-4f05ba4a54d3","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"会议录音n↓n音频预处理n↓nASR 语音识别n↓n文本结构化n↓n会议纪要生成n↓n待办事项提取n↓n会议资料归档与检索n"}]},{"type":"paragraph","attrs":{"id":"79e2d1f3-8dcf-46d8-a87b-07adcd297f48","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"本文以 Qwen ASR 1.7B 为基础,演示如何从本地模型推理开始,逐步封装接口、处理长会议录音,并把转写结果接入上层会议处理系统。本文的集成链路中,ASR 之后的会议纪要、待办和归档环节由熙瑾会悟承接。"}]},{"type":"heading","attrs":{"id":"a6126852-48f5-4f07-8d62-913fe0b33b8f","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"二、为什么选择 Qwen ASR 1.7B 做本地会议识别"}]},{"type":"paragraph","attrs":{"id":"60b7eb4a-749b-44aa-8745-5db0499b8802","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"在会议场景中,ASR 模型至少要满足几个要求:"}]},{"type":"paragraph","attrs":{"id":"bc9ff0a6-e51d-4b78-8166-6087430eeb33","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第一,可以本地部署,避免会议音频依赖外部服务。"}]},{"type":"paragraph","attrs":{"id":"5c05fd81-d6a1-45af-b25c-eff08ba10a9c","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第二,支持中文会议中的常见表达和专业术语。"}]},{"type":"paragraph","attrs":{"id":"97813e86-cd57-4dab-b5f8-6628641c6636","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第三,可以通过接口被会议系统调用,而不是只能在命令行里测试。"}]},{"type":"paragraph","attrs":{"id":"501f9746-8c2c-4f1f-8fa2-ccfa24700895","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第四,具备一定的多语种和混合语言处理能力,适合技术会议、跨部门会议和培训场景。"}]},{"type":"paragraph","attrs":{"id":"bb8daaea-8f8e-41b4-8afd-893eb8edbd42","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"Qwen ASR 1.7B 适合放在会议系统的语音识别层。它负责将会议音频转换成文本,上层会议系统再继续做文本整理、纪要生成、待办提取和归档检索。"}]},{"type":"paragraph","attrs":{"id":"b05ea6da-239a-414d-bf85-196910f86eef","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这个定位很重要。"}]},{"type":"paragraph","attrs":{"id":"8c58e4d5-8ca6-4b7c-9007-1bf21dc07de3","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"ASR 解决的是“听清楚”,会议处理系统解决的是“整理清楚、追踪清楚、沉淀清楚”。"}]},{"type":"heading","attrs":{"id":"b9aed761-c295-4d82-96a4-df17b94c8a0a","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"三、环境准备:先把本地 ASR 推理跑起来"}]},{"type":"paragraph","attrs":{"id":"e786e2e2-ae7a-4b8d-b258-ede66d1ed56e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"为了贴近本地化部署场景,这里不使用在线 API,而是从本地环境开始。"}]},{"type":"paragraph","attrs":{"id":"f820c323-d158-47da-a769-43e5b45aece9","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"推荐环境如下:"}]},{"type":"table","attrs":{"id":"09f8a919-deed-4103-9bcb-ddf680ecd420","isHoverDragHandle":false},"content":[{"type":"tableRow","content":[{"type":"tableHeader","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"23af428f-8df8-45c5-819e-e3571220d9e4","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"配置项"}]}]},{"type":"tableHeader","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"68c1e65f-ca8e-4781-be68-edc785d3b778","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"建议配置"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"52220e33-9ccd-47a8-b7a6-22b9268812ab","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"操作系统"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"4e17bb54-39f0-46d6-a5d8-b8a9127951ef","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"Ubuntu 20.04 / 22.04 或其他 Linux 服务器环境"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"f77d26fd-9301-4e95-83a3-c1e4719b3f31","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"Python"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"e2861ffc-8d6e-4b9d-967f-e855d5f12d47","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"Python 3.10 "}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"f9267180-7082-436f-9704-cceaa74a26c5","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"GPU"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"4c2eba9a-225f-46a7-8425-b806a7b65f9f","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"建议 16GB 显存以上"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"9f387107-6ee8-40b1-be03-2647bc21b4fc","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"音频工具"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"74dd0c75-b70f-4a1c-bf56-59a4edb37599","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"ffmpeg"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"8368d6a4-dc1c-413a-9809-acdb69e96816","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"服务框架"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"bc0612d0-563b-4373-a0ab-03c9ea6ab839","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"FastAPI / Uvicorn"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"b93b93b5-a143-4ff8-ae4d-f7fbcc42997d","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"ASR 模型"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"15e6a1c6-94e3-4d13-81e6-3c3341f3f089","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"Qwen ASR 1.7B"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"17704853-c445-4050-9513-05f9b63cbb00","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"上层处理"}]}]},{"type":"tableCell","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"background":null,"color":null,"textAlign":null,"style":null},"content":[{"type":"paragraph","attrs":{"id":"a3adc7a4-fc21-440b-9f96-a5f3b2cb858d","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"会议纪要、待办、归档系统"}]}]}]}]},{"type":"paragraph","attrs":{"id":"f585a505-0df8-4525-928f-c2f6c84719d0","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"创建独立环境:"}]},{"type":"codeBlock","attrs":{"id":"1a1d318a-90d6-466c-8d12-df43fb5c1391","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"conda create -n meeting-asr python=3.12 -ynconda activate meeting-asrnnpip install -U qwen-asrnpip install fastapi uvicorn python-multipart requests pydubn"}]},{"type":"paragraph","attrs":{"id":"f9417b27-57c0-4f64-9fb5-b79fddec609f","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"如果部署服务器可以访问模型仓库,可以直接下载模型;如果是内网环境,建议提前下载模型文件,再拷贝到目标服务器。"}]},{"type":"codeBlock","attrs":{"id":"c3b7b4c8-3e6f-4371-8196-da0836de5b89","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"pip install -U modelscopenmodelscope download --model Qwen/Qwen3-ASR-1.7B --local_dir ./models/Qwen3-ASR-1.7Bn"}]},{"type":"paragraph","attrs":{"id":"aa24070b-07b9-480a-8872-777a40e6433e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"部署建议:正式交付时,不建议运行时再自动下载模型。更稳妥的方式是把模型权重、代码、镜像、配置文件和启动脚本一起准备好,现场只做加载和验证。"}]},{"type":"heading","attrs":{"id":"610f1adb-10bd-4f07-9458-f3e123b534a1","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"四、第一次推理:验证模型能否正常识别会议录音"}]},{"type":"paragraph","attrs":{"id":"35c9e511-2310-44b2-b2f3-87de2f9665f2","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"模型部署完成后,先不要急着封装 API。第一步应该先用最小代码验证模型是否能正常推理。"}]},{"type":"paragraph","attrs":{"id":"c840fc7b-cd6e-479a-874f-34172dfbe249","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"准备一段测试音频:"}]},{"type":"codeBlock","attrs":{"id":"84f5817e-d67c-43a9-94ed-ef1b1c2c5d45","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"./samples/meeting_10s.wavn"}]},{"type":"paragraph","attrs":{"id":"e048fdcd-b5a0-40f6-8668-b0d37d6727c7","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"新建 "},{"type":"text","marks":[{"type":"code"}],"text":"test_asr.py"},{"type":"text","text":":"}]},{"type":"codeBlock","attrs":{"id":"3fee950b-05b4-4b7c-b1c2-b35d4250fc71","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"import torchnfrom qwen_asr import Qwen3ASRModelnnMODEL_PATH = "./models/Qwen3-ASR-1.7B"nAUDIO_PATH = "./samples/meeting_10s.wav"nnmodel = Qwen3ASRModel.from_pretrained(nMODEL_PATH,ndtype=torch.bfloat16,ndevice_map="cuda:0",nmax_inference_batch_size=8,nmax_new_tokens=512,n)nnresults = model.transcribe(naudio=AUDIO_PATH,nlanguage=None,n)nnfor r in results:nprint("识别语言:", r.language)nprint("识别文本:", r.text)n"}]},{"type":"paragraph","attrs":{"id":"e09c82c7-70fb-4f70-8758-94a28cab121c","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"执行:"}]},{"type":"codeBlock","attrs":{"id":"1b59e040-b646-4f91-8abe-795be6e9ad50","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"python test_asr.pyn"}]},{"type":"paragraph","attrs":{"id":"3b236d3a-98a8-43eb-9c89-3480f64d6e27","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"如果输出类似下面的结果,说明模型链路已经打通:"}]},{"type":"codeBlock","attrs":{"id":"d167675a-9611-4806-9d50-9c35f68d7efe","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"识别语言:Chinesen识别文本:本次项目评审会主要讨论三个问题,第一是本地化部署环境,第二是会议转写准确率,第三是会后纪要自动生成。n"}]},{"type":"paragraph","attrs":{"id":"1d66b212-1e76-4f32-a7f3-622d5badda30","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这一步主要验证三件事:"}]},{"type":"paragraph","attrs":{"id":"79a3f340-e051-4e75-84f8-8e41d6b361bb","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第一,模型权重是否完整。"}]},{"type":"paragraph","attrs":{"id":"c103000c-f879-4f8f-b606-0f02cebc9af5","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第二,GPU 环境是否可用。"}]},{"type":"paragraph","attrs":{"id":"8daf3790-2956-4907-85ed-2c10ac489d3a","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第三,音频格式是否能被正常读取。"}]},{"type":"paragraph","attrs":{"id":"7a378e0c-bc4c-4f66-8561-4e397ee40eb7","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"如果最小推理都不能跑通,就不要急着接入上层系统。很多部署问题并不是业务代码导致的,而是模型文件、显卡环境、依赖版本或音频格式在底层就没有稳定。"}]},{"type":"heading","attrs":{"id":"01f21708-97e7-436a-926c-68cd5b4cfdb3","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"五、音频格式处理:统一转成 16kHz 单声道 WAV"}]},{"type":"paragraph","attrs":{"id":"d7cbc7c8-478a-4f65-b620-88554bb835b3","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"实际会议录音的格式非常复杂,可能是 mp3、m4a、aac、wav,也可能来自线上会议软件、录播设备或手机录音。"}]},{"type":"paragraph","attrs":{"id":"d500a401-c091-4a19-a8ac-11b9cbe0e95a","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"为了减少识别波动,建议进入 ASR 前统一转成 16kHz、单声道 WAV。"}]},{"type":"paragraph","attrs":{"id":"68b71aae-d32f-4e35-a35f-fbfa0aaa918d","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"安装 ffmpeg:"}]},{"type":"codeBlock","attrs":{"id":"04aaed93-3952-46ad-a8de-475c2cbede70","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"sudo apt-get updatensudo apt-get install -y ffmpegn"}]},{"type":"paragraph","attrs":{"id":"bdf0578b-c89f-4b59-b490-e197d9dd79c1","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"单个文件转换:"}]},{"type":"codeBlock","attrs":{"id":"9e5de66e-bbd7-4e94-92e2-8b0c291f9bb0","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"ffmpeg -y -i input.mp3 -ar 16000 -ac 1 output.wavn"}]},{"type":"paragraph","attrs":{"id":"dbe74e9f-794e-4abe-82c4-7b0d93f20bcd","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"批量转换会议目录:"}]},{"type":"codeBlock","attrs":{"id":"9f7f180b-c964-4588-9eac-129bf9a7c31b","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"mkdir -p ./wav_meetingsnnfor file in ./raw_meetings/*; donname=$(basename "$file")nbase="${name%.*}"nffmpeg -y -i "$file" -ar 16000 -ac 1 "./wav_meetings/${base}.wav"ndonen"}]},{"type":"paragraph","attrs":{"id":"d4fa5390-2a66-45d0-be09-f5d99d3da12a","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"也可以封装成 Python 函数:"}]},{"type":"codeBlock","attrs":{"id":"2a678a31-ea42-45ab-a291-b392799ff455","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"from pathlib import Pathnfrom pydub import AudioSegmentnndef normalize_audio(input_path: str, output_dir: str = "./normalized") -> str:n"""n将常见会议录音格式统一转为 16kHz、单声道 WAV。n"""ninput_path = Path(input_path)noutput_dir = Path(output_dir)noutput_dir.mkdir(parents=True, exist_ok=True)nnoutput_path = output_dir / f"{input_path.stem}.wav"nnaudio = AudioSegment.from_file(input_path)naudio = audio.set_frame_rate(16000).set_channels(1)naudio.export(output_path, format="wav")nnreturn str(output_path)n"}]},{"type":"paragraph","attrs":{"id":"d635aec3-5f8c-49c1-a1e2-4b5b4aa3a75f","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这一步看起来简单,但在真实会议场景中非常重要。很多识别不稳定的问题,并不是模型本身导致的,而是输入音频采样率、声道、编码或音量不一致造成的。"}]},{"type":"heading","attrs":{"id":"68defff4-08a1-4853-a470-0708c0c3c2af","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"六、封装 FastAPI:把 ASR 模型变成内部服务"}]},{"type":"paragraph","attrs":{"id":"8ec81af5-9a97-4ede-8b53-09a2d1cccdf9","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"单机脚本只能用于验证,不能直接进入业务系统。更稳妥的方式是把 ASR 封装成一个内部 HTTP 服务,让会议系统通过接口调用。"}]},{"type":"paragraph","attrs":{"id":"6d5b5dfe-3a4d-432f-8fd2-0a49c65327f9","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"新建 "},{"type":"text","marks":[{"type":"code"}],"text":"asr_server.py"},{"type":"text","text":":"}]},{"type":"codeBlock","attrs":{"id":"631b805d-2e90-4320-a0e9-2d04ba853c77","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"import timenimport tempfilenfrom pathlib import Pathnfrom typing import Optionalnnimport torchnfrom fastapi import FastAPI, UploadFile, File, Formnfrom pydantic import BaseModelnfrom qwen_asr import Qwen3ASRModelnnMODEL_PATH = "./models/Qwen3-ASR-1.7B"nnapp = FastAPI(title="Meeting ASR Service", version="1.0.0")nnmodel = Qwen3ASRModel.from_pretrained(nMODEL_PATH,ndtype=torch.bfloat16,ndevice_map="cuda:0",nmax_inference_batch_size=8,nmax_new_tokens=1024,n)nnclass ASRResponse(BaseModel):nlanguage: strntext: strnduration_sec: floatnprocess_sec: floatnrtf: [email protected]("/health")ndef health_check():nreturn {"status": "ok", "model": "Qwen3-ASR-1.7B"}[email protected]("/asr", response_model=ASRResponse)nasync def transcribe(naudio_file: UploadFile = File(...),nlanguage: Optional[str] = Form(default=None),n):nsuffix = Path(audio_file.filename).suffix or ".wav"nnwith tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:ntmp.write(await audio_file.read())ntmp_path = tmp.namennstart = time.time()nnresults = model.transcribe(naudio=tmp_path,nlanguage=language,n)nnprocess_sec = time.time() - startnresult = results[0]nnduration_sec = 0.0nnreturn {n"language": result.language,n"text": result.text,n"duration_sec": duration_sec,n"process_sec": round(process_sec, 3),n"rtf": 0.0 if duration_sec == 0 else round(duration_sec / process_sec, 3),n}n"}]},{"type":"paragraph","attrs":{"id":"467a0bc6-1ea9-4328-a7dc-c31032b23732","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"启动服务:"}]},{"type":"codeBlock","attrs":{"id":"f33f1f10-1f35-49be-a7c7-5bd0e2276f6b","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"uvicorn asr_server:app --host 0.0.0.0 --port 7861n"}]},{"type":"paragraph","attrs":{"id":"06eaa95c-441a-44cc-afb0-bf66db9bb981","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"测试健康检查:"}]},{"type":"codeBlock","attrs":{"id":"f8bca7df-7c81-4fac-b1bf-b26565628b44","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"curl http://127.0.0.1:7861/healthn"}]},{"type":"paragraph","attrs":{"id":"c6fc9120-5497-4f16-9111-abe1bbe5df20","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"返回示例:"}]},{"type":"codeBlock","attrs":{"id":"598a1c04-a5fd-4961-836f-a13bfeb77ec3","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"{n"status": "ok",n"model": "Qwen3-ASR-1.7B"n}n"}]},{"type":"paragraph","attrs":{"id":"9d557160-07a4-4a24-813a-cf7a101f374a","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"上传会议录音测试:"}]},{"type":"codeBlock","attrs":{"id":"01a11188-4bff-4bdd-af80-4069e85c3b42","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"curl -X POST "http://127.0.0.1:7861/asr" n-F "audio_file=@./samples/meeting_10s.wav" n-F "language=Chinese"n"}]},{"type":"paragraph","attrs":{"id":"b71bc81e-16ba-45f9-8ec7-76c78039ba43","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"返回示例:"}]},{"type":"codeBlock","attrs":{"id":"62afb20b-66f0-414d-9ef1-3d118ffda9f4","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"{n"language": "Chinese",n"text": "本次会议主要确认本地化部署方案,并讨论会议纪要自动生成的上线计划。",n"duration_sec": 0.0,n"process_sec": 1.842,n"rtf": 0.0n}n"}]},{"type":"paragraph","attrs":{"id":"3e1b5329-6823-46e9-bb7b-81463f77e83a","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"到这里,一个最小可用的本地 ASR 服务就完成了。它可以被会议系统调用,也可以作为后续纪要生成链路的前置输入。"}]},{"type":"heading","attrs":{"id":"849173d8-7234-4ac7-90f3-24796c5147ee","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"七、增加音频时长、RTF 和日志输出"}]},{"type":"paragraph","attrs":{"id":"dbb620ab-6ca5-474b-88d0-7bc72e72cbcf","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"企业部署不能只看“能不能返回文本”,还要看服务是否可观测。至少需要记录每次请求的文件名、音频时长、处理耗时、RTF 和错误信息。"}]},{"type":"paragraph","attrs":{"id":"f8ef4ee4-655f-4dc7-9e3e-be0acc94fb47","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"可以用 "},{"type":"text","marks":[{"type":"code"}],"text":"ffprobe"},{"type":"text","text":" 获取音频时长:"}]},{"type":"codeBlock","attrs":{"id":"dc7de3da-ca85-46f4-b53e-fcb9377abfb6","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"import jsonnimport subprocessnndef get_audio_duration(audio_path: str) -> float:n"""n使用 ffprobe 获取音频时长,单位:秒。n"""ncmd = [n"ffprobe",n"-v", "quiet",n"-print_format", "json",n"-show_format",naudio_path,n]noutput = subprocess.check_output(cmd).decode("utf-8")ninfo = json.loads(output)nreturn float(info["format"]["duration"])n"}]},{"type":"paragraph","attrs":{"id":"5b438c7c-3a1b-40b6-82f4-f3c4807eb076","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"将它加入接口:"}]},{"type":"codeBlock","attrs":{"id":"5b993084-e0d4-4ab7-873f-769375748d44","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"@app.post("/asr", response_model=ASRResponse)nasync def transcribe(naudio_file: UploadFile = File(...),nlanguage: Optional[str] = Form(default=None),n):nsuffix = Path(audio_file.filename).suffix or ".wav"nnwith tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:ntmp.write(await audio_file.read())ntmp_path = tmp.namennduration_sec = get_audio_duration(tmp_path)nnstart = time.time()nresults = model.transcribe(audio=tmp_path, language=language)nprocess_sec = time.time() - startnnrtf = duration_sec / process_sec if process_sec > 0 else 0nresult = results[0]nnprint(nf"[ASR] file={audio_file.filename}, "nf"duration={duration_sec:.2f}s, "nf"process={process_sec:.2f}s, "nf"rtf={rtf:.2f}x, "nf"lang={result.language}"n)nnreturn {n"language": result.language,n"text": result.text,n"duration_sec": round(duration_sec, 3),n"process_sec": round(process_sec, 3),n"rtf": round(rtf, 3),n}n"}]},{"type":"paragraph","attrs":{"id":"f8950649-fdfa-406b-abc4-a0c8e535139e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"日志示例:"}]},{"type":"codeBlock","attrs":{"id":"432d215b-bebe-4f6b-bea8-88109af12631","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"[ASR] file=meeting_20260706.wav, duration=312.54s, process=48.63s, rtf=6.43x, lang=Chinesen"}]},{"type":"paragraph","attrs":{"id":"f26fe601-f47a-4be1-952c-adbab8420835","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"RTF 是会议转写服务中很重要的指标。它可以帮助判断当前服务是否能支撑会后快速生成转写初稿,也能帮助运维定位 GPU 负载和长音频处理瓶颈。"}]},{"type":"heading","attrs":{"id":"99f25e3b-76a8-40dd-838c-618ee999eb70","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"八、长会议处理:不要把 2 小时录音直接丢给模型"}]},{"type":"paragraph","attrs":{"id":"1ae674e8-bf54-4a1d-90be-cf8a0aa95e8d","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"真实会议经常超过 1 小时。工程上不建议把超长文件一次性丢给模型。更稳妥的方式是先分段,再转写,最后合并。"}]},{"type":"paragraph","attrs":{"id":"094643e4-f7aa-476d-84ec-488b0f9111b3","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"常见分段方式有三种:"}]},{"type":"paragraph","attrs":{"id":"6240c541-3934-4fae-a17f-ce1a45f43e88","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第一,固定时长切分,例如每 120 秒切一段,实现简单。"}]},{"type":"paragraph","attrs":{"id":"861c84d5-e1e3-4278-ae69-bd136e45e16d","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第二,静音检测切分,在停顿处断开,语义更完整。"}]},{"type":"paragraph","attrs":{"id":"292a08c9-bcd4-4333-98ee-d93d4575f81b","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第三,重叠切分,每段保留 2 到 5 秒重叠,避免句子被切断。"}]},{"type":"paragraph","attrs":{"id":"eed3fbdf-552e-4c38-83bc-e8b8cffcc056","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"下面是一个固定时长切分脚本:"}]},{"type":"codeBlock","attrs":{"id":"f8805778-e1c7-4214-99a2-2db4171ae36b","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"from pydub import AudioSegmentnfrom pathlib import Pathnndef split_audio_fixed(nwav_path: str,noutput_dir: str = "./segments",nchunk_ms: int = 120_000,noverlap_ms: int = 3_000,n):n"""n将长会议录音切成多个短片段。nchunk_ms: 每段长度,默认 120 秒noverlap_ms: 相邻片段重叠,默认 3 秒n"""nwav_path = Path(wav_path)noutput_dir = Path(output_dir) / wav_path.stemnoutput_dir.mkdir(parents=True, exist_ok=True)nnaudio = AudioSegment.from_wav(wav_path)nsegments = []nnstart = 0nindex = 1nnwhile start < len(audio):nend = min(start chunk_ms, len(audio))nsegment = audio[start:end]nnsegment_path = output_dir / f"{wav_path.stem}_{index:04d}.wav"nsegment.export(segment_path, format="wav")nnsegments.append(str(segment_path))nnif end >= len(audio):nbreaknnstart = end - overlap_msnindex = 1nnreturn segmentsn"}]},{"type":"paragraph","attrs":{"id":"a4495eec-ad60-49df-a791-8e933b5fd9e2","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"批量调用 ASR 接口并合并结果:"}]},{"type":"codeBlock","attrs":{"id":"b3c80613-8b82-4951-9d28-665fdd3ebce9","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"import requestsnnASR_API = "http://127.0.0.1:7861/asr"nndef transcribe_segments(segment_paths):ntexts = []nnfor i, path in enumerate(segment_paths, start=1):nwith open(path, "rb") as f:nresp = requests.post(nASR_API,nfiles={"audio_file": f},ndata={"language": "Chinese"},ntimeout=300,n)nresp.raise_for_status()ndata = resp.json()nnprint(f"片段 {i}/{len(segment_paths)} 完成:{data['text'][:40]}...")ntexts.append(data["text"])nnreturn "n".join(texts)nnif __name__ == "__main__":nsegments = split_audio_fixed("./wav_meetings/project_review.wav")nfull_text = transcribe_segments(segments)nnwith open("./project_review_transcript.txt", "w", encoding="utf-8") as f:nf.write(full_text)n"}]},{"type":"paragraph","attrs":{"id":"3ade52d0-00b3-4c3f-bc91-e58782575564","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这一步完成后,可以得到完整会议转写文本。但它仍然只是“听写稿”,还不是可直接使用的会议纪要。"}]},{"type":"heading","attrs":{"id":"b2e6467f-883a-4856-bbdf-a10f91120a7e","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"九、接入会议处理层:从 ASR 文本到会议纪要"}]},{"type":"paragraph","attrs":{"id":"a2d5b31b-0e97-46a0-9e00-098c0ee2e92c","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"ASR 文本进入业务流程后,通常还需要继续处理。"}]},{"type":"paragraph","attrs":{"id":"357e7645-2de7-41d9-bdf4-9b8114535ac7","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"一个典型会议处理链路如下:"}]},{"type":"codeBlock","attrs":{"id":"fb5bf1fb-9342-4b4f-b07b-c2d19d71761d","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"会议录音n↓n音频预处理:格式转换、采样率统一、音频切分n↓nQwen ASR 1.7B:会议语音转写n↓n文本结构化:段落整理、口语清洗、术语修正n↓n会议纪要生成:摘要、议题、决策、待办、风险点n↓n会议归档:全文检索、权限控制、资料沉淀n"}]},{"type":"paragraph","attrs":{"id":"eb152603-a39a-4b6b-a3db-25561b026d45","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"在本文的集成链路中,熙瑾会悟位于 ASR 之后,负责承接转写文本并继续完成会议摘要、议题归纳、待办提取和归档检索。这样 ASR 模型不需要直接面对最终用户,而是作为会议内容处理流程中的前置能力节点。"}]},{"type":"paragraph","attrs":{"id":"ff582f20-41db-48e2-b869-0f827c8a3354","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"示例:把前面生成的转写文本提交给会议处理接口。"}]},{"type":"paragraph","attrs":{"id":"00ec50e6-8c58-405e-bae2-d920d4897671","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"下面的 "},{"type":"text","marks":[{"type":"code"}],"text":"MEETING_API"},{"type":"text","text":" 是示例地址,实际部署时需要替换为现场真实接口。"}]},{"type":"codeBlock","attrs":{"id":"55061b80-8a95-489b-82ee-69af94b594b9","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"import requestsnfrom datetime import datetimennMEETING_API = "http://127.0.0.1:18080/api/meeting/minutes/generate"nndef submit_to_meeting_system(transcript_text: str):npayload = {n"meeting_title": "本地语音识别服务部署评审会",n"meeting_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),n"participants": ["项目负责人", "运维工程师", "产品经理", "客户代表"],n"asr_model": "Qwen-ASR-1.7B",n"source": "local_asr",n"transcript": transcript_text,n"output_format": {n"summary": True,n"topics": True,n"decisions": True,n"todos": True,n"risks": Truen}n}nnresp = requests.post(MEETING_API, json=payload, timeout=300)nresp.raise_for_status()nreturn resp.json()n"}]},{"type":"paragraph","attrs":{"id":"01ba4fe0-114b-41ac-b3e9-9873bbb6877e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"返回结果可以设计成结构化 JSON:"}]},{"type":"codeBlock","attrs":{"id":"6df6a15e-70ed-45e1-b1bc-4f47f7693731","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"{n"summary": "本次会议主要讨论了 Qwen ASR 1.7B 在本地会议转写链路中的接入方案,确认了音频预处理、ASR 服务封装、长音频切分和纪要生成流程。",n"topics": [n"Qwen ASR 1.7B 本地部署",n"会议录音格式统一与长音频切分",n"ASR 服务接口封装",n"会议纪要生成与资料归档"n],n"decisions": [n"ASR 服务以内网 FastAPI 方式提供给会议系统调用",n"会议录音统一转为 16kHz 单声道 WAV 后再进入识别流程",n"超过 30 分钟的会议录音采用分段识别与结果合并机制"n],n"todos": [n{n"owner": "运维工程师",n"task": "完成 Qwen ASR 1.7B 模型离线部署和服务化启动脚本",n"deadline": "本周五"n},n{n"owner": "产品经理",n"task": "确认会议纪要模板和输出格式",n"deadline": "下周二"n}n],n"risks": [n"长会议场景下需要关注显存占用和并发队列",n"嘈杂会议室需要优化麦克风采集和音频预处理"n]n}n"}]},{"type":"paragraph","attrs":{"id":"f8d0f93c-0667-434f-80bc-b34b9b670e6f","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"到这里,系统才真正从“ASR 模型”变成了“会议处理链路”。"}]},{"type":"paragraph","attrs":{"id":"a38e6a5c-f7b1-4108-9b7c-da8ac756446b","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"因为用户最终需要的不是模型日志,也不是连续转写文本,而是可以直接使用的会议成果:摘要、议题、决策、待办、风险和归档记录。"}]},{"type":"heading","attrs":{"id":"e55e1e6c-f95a-4954-b8fa-68a6488cef7d","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"十、批量处理历史会议:把存量录音变成可检索资料"}]},{"type":"paragraph","attrs":{"id":"be0799a6-14f7-4544-9a96-c92697d69756","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"很多系统上线后,不仅要处理新会议,也需要处理过去积累的大量会议录音。"}]},{"type":"paragraph","attrs":{"id":"610f2aba-c749-4a74-891f-c32ddea960a8","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"可以写一个批处理脚本,把目录里的录音统一处理。"}]},{"type":"codeBlock","attrs":{"id":"3874c008-3691-4c8c-a906-fd328ec38252","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"from pathlib import Pathnimport jsonnndef process_meeting_folder(raw_dir: str):nraw_dir = Path(raw_dir)nresults = []nnfor file in raw_dir.iterdir():nif file.suffix.lower() not in [".mp3", ".wav", ".m4a", ".aac"]:ncontinuennprint(f"n开始处理:{file.name}")nnwav_path = normalize_audio(str(file))nsegments = split_audio_fixed(wav_path)ntranscript = transcribe_segments(segments)nnmeeting_result = submit_to_meeting_system(transcript)nnitem = {n"filename": file.name,n"wav_path": wav_path,n"transcript": transcript,n"minutes": meeting_result,n}nnresults.append(item)nnoutput_path = Path("./outputs") / f"{file.stem}.json"noutput_path.parent.mkdir(parents=True, exist_ok=True)nnwith open(output_path, "w", encoding="utf-8") as f:njson.dump(item, f, ensure_ascii=False, indent=2)nnprint(f"处理完成:{output_path}")nnreturn resultsnnif __name__ == "__main__":nprocess_meeting_folder("./raw_meetings")n"}]},{"type":"paragraph","attrs":{"id":"b448cd6f-3c21-4a1b-aed6-f199c44006db","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这个脚本可以用于历史会议资料入库:"}]},{"type":"paragraph","attrs":{"id":"0a67813d-1315-4034-b42d-f3abc1551935","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"把过去散落在文件夹里的录音统一转成文本,再提炼成结构化纪要,最后进入会议资料库,支持后续按项目、人员、时间、关键词进行检索。"}]},{"type":"paragraph","attrs":{"id":"5d4b524f-1008-44d7-89e4-56089e17ddb5","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这一步的价值不只是节省听录音时间,更重要的是让会议内容变成可以复用的资料。"}]},{"type":"heading","attrs":{"id":"01424763-e4c8-43ee-b8c6-d797581bea02","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"十一、本地部署建议:不要只部署模型,要部署完整链路"}]},{"type":"paragraph","attrs":{"id":"262b43c2-cb82-4d35-84aa-902520ecbd35","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"在本地部署中,不建议把 ASR、会议后端、总结模型、数据库全部塞进一个服务里。更稳妥的方式是拆分部署,便于独立升级、扩容和排障。"}]},{"type":"paragraph","attrs":{"id":"2401fbaa-f5ce-4040-be67-9ee76d9dfe12","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"一个相对稳妥的部署结构如下:"}]},{"type":"codeBlock","attrs":{"id":"8fdb7a9a-91ea-448d-a689-441334d8635c","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"Nginx / 网关n├── 会议系统前端n├── 会议系统业务后端n├── 文件服务:会议录音、附件、纪要文件n├── ASR 服务:Qwen ASR 1.7Bn├── 会议总结模型服务n├── Redis / MySQL / Elasticsearchn└── 日志与监控n"}]},{"type":"paragraph","attrs":{"id":"089e04a4-3058-41c6-85bc-6a34c65362ab","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"ASR 服务建议单独容器化:"}]},{"type":"codeBlock","attrs":{"id":"c88d21bc-533d-4ced-8f1d-daf31629ee47","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"version: "3.8"nnservices:nmeeting-qwen-asr:nimage: meeting/qwen-asr:1.7bncontainer_name: meeting-qwen-asrnrestart: alwaysnports:n- "7861:7861"nvolumes:n- ./models/Qwen3-ASR-1.7B:/app/models/Qwen3-ASR-1.7Bn- ./logs:/app/logsn- ./tmp:/app/tmpnenvironment:n- MODEL_PATH=/app/models/Qwen3-ASR-1.7Bn- CUDA_VISIBLE_DEVICES=0n- MAX_BATCH_SIZE=8n- MAX_NEW_TOKENS=1024ncommand: >nuvicorn asr_server:appn--host 0.0.0.0n--port 7861n"}]},{"type":"paragraph","attrs":{"id":"c2db74f0-0f85-4fad-b0ef-38f8e333b1e1","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"业务系统配置中只需要指定 ASR 服务地址:"}]},{"type":"codeBlock","attrs":{"id":"ca60c4bf-07b1-4f30-a280-d5ebc680ff94","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"ASR_PROVIDER=qwennASR_MODEL=Qwen-ASR-1.7BnASR_BASE_URL=http://meeting-qwen-asr:7861nASR_TRANSCRIBE_PATH=/asrnASR_LANGUAGE=Chinesen"}]},{"type":"paragraph","attrs":{"id":"6e55735b-a730-461f-b362-89377e313df6","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这样做的好处是:"}]},{"type":"paragraph","attrs":{"id":"a7afd096-e3fc-43d2-8fba-27a0bf7a3d5c","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第一,ASR 模型升级不影响主业务系统。"}]},{"type":"paragraph","attrs":{"id":"44ffbe9b-26bc-4511-a301-2c9b1f48beac","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第二,ASR 服务可以单独扩容或迁移 GPU 节点。"}]},{"type":"paragraph","attrs":{"id":"8a18721d-76fc-47cd-bbae-c051351b2a2e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第三,识别链路异常时,运维可以直接查看 ASR 服务日志。"}]},{"type":"paragraph","attrs":{"id":"e8349593-b5b3-43f9-a722-a759ddf687a9","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"第四,后续如果需要切换其他 ASR 引擎,也可以通过统一接口适配。"}]},{"type":"heading","attrs":{"id":"0c0588f2-8ad1-463d-a4df-8d567a2427d2","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"十二、常见问题:部署时最容易踩的几个坑"}]},{"type":"heading","attrs":{"id":"7be808d1-6325-4c56-a2bc-d6ca2a9ec582","textAlign":"inherit","indent":0,"level":3,"isHoverDragHandle":false},"content":[{"type":"text","text":"1. 显存不足"}]},{"type":"paragraph","attrs":{"id":"8bbea686-54a4-4492-8548-1bad216aeaae","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"如果启动时出现 CUDA OOM,可以先降低 batch size:"}]},{"type":"codeBlock","attrs":{"id":"2ac53d67-62aa-4534-ad34-c81abb22581c","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"max_inference_batch_size=1nmax_new_tokens=512n"}]},{"type":"paragraph","attrs":{"id":"9612a254-daf6-4105-a26b-d7275ae26b68","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"也可以在服务侧限制并发,让会议录音排队处理,而不是同时把多个长音频送进 GPU。"}]},{"type":"heading","attrs":{"id":"71de8601-564a-4c82-b4b8-cef99690612e","textAlign":"inherit","indent":0,"level":3,"isHoverDragHandle":false},"content":[{"type":"text","text":"2. 识别速度慢"}]},{"type":"paragraph","attrs":{"id":"efe7d4c9-9482-4aa4-9e39-6156d11b06a4","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"先看三个指标:"}]},{"type":"codeBlock","attrs":{"id":"6900d137-45df-44de-b8de-074b842ac501","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"音频时长 duration_secn处理耗时 process_secn实时因子 rtfn"}]},{"type":"paragraph","attrs":{"id":"8785ce6b-c5e7-4c29-a269-082876f67cb0","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"如果 RTF 很低,说明 GPU 推理速度不理想。可以检查是否有其他进程占用显存、音频是否过长、是否需要切分、推理参数是否合理。"}]},{"type":"heading","attrs":{"id":"6ef4c69b-5222-4832-b9d8-39117a0c0367","textAlign":"inherit","indent":0,"level":3,"isHoverDragHandle":false},"content":[{"type":"text","text":"3. 长会议文本重复或断句不自然"}]},{"type":"paragraph","attrs":{"id":"3711178e-a1c6-41e9-8b7e-2174d184474e","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这通常和分段策略有关。固定切分容易切断句子,可以改成静音检测切分,或者增加 2 到 5 秒重叠,再在合并阶段做去重。"}]},{"type":"heading","attrs":{"id":"da03511f-9b42-4bae-a960-ba76e0b066eb","textAlign":"inherit","indent":0,"level":3,"isHoverDragHandle":false},"content":[{"type":"text","text":"4. 专业术语识别不稳定"}]},{"type":"paragraph","attrs":{"id":"a4d0d082-6993-41c5-ac81-4a3751db77fd","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"会议系统最好增加术语后处理模块。例如企业名、人名、项目代号、产品名、缩写词,可以在 ASR 后做替换和规范化。"}]},{"type":"codeBlock","attrs":{"id":"55d81b00-a46d-420d-be30-95b07d5b787b","language":"javascript","theme":"atom-one-dark","runtimes":0,"isHoverDragHandle":false,"key":"","languageByAi":"javascript"},"content":[{"type":"text","text":"def normalize_terms(text: str) -> str:nterm_map = {n"Q 文 ASR": "Qwen ASR",n"GPU 利用": "GPU 利用率",n"action item": "Action Item",n"会议机要": "会议纪要",n}nnfor wrong, right in term_map.items():ntext = text.replace(wrong, right)nnreturn textn"}]},{"type":"paragraph","attrs":{"id":"5fb55908-1402-47aa-a20e-6f3761f577eb","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"术语表在实际项目中非常重要。每个单位都有自己的简称、人名、项目代号和专业词,这些并不能完全依赖通用模型一次识别准确。"}]},{"type":"heading","attrs":{"id":"b443add3-86ca-47d5-a514-bd35a5c0c201","textAlign":"inherit","indent":0,"level":2,"isHoverDragHandle":false},"content":[{"type":"text","text":"十三、总结:ASR 是入口,会议结构化才是落点"}]},{"type":"paragraph","attrs":{"id":"d27c09b4-b626-43ef-b2eb-406d8b4a7771","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"从这次实践可以看到,Qwen ASR 1.7B 可以为会议系统提供本地语音识别能力。通过 FastAPI 封装后,它可以变成一个可被内部系统调用的 ASR 服务;再配合音频预处理、长音频切分、批量转写、术语修正和纪要生成,就能形成一条完整的会议处理链路。"}]},{"type":"paragraph","attrs":{"id":"8a036ae3-e374-44c9-abbe-6b88a0348c61","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"单独部署 ASR,解决的是“把声音变成文字”。"}]},{"type":"paragraph","attrs":{"id":"9e4b9355-d51b-484c-b1f6-194b6af289f6","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"接入会议处理层后,解决的是“把会议变成资料、把资料变成知识、把知识变成可追踪的行动”。"}]},{"type":"paragraph","attrs":{"id":"d4da0733-390e-4287-9b38-61417b647da7","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"这也是熙瑾会悟在链路中的位置:它承接 ASR 之后的文本结构化、纪要生成、待办提取和归档检索,让会议内容从原始转写稿进一步变成可阅读、可管理、可复用的会议成果。"}]},{"type":"paragraph","attrs":{"id":"becd0c3a-a478-4a48-a889-1f628f1b3ad5","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"对于实际部署来说,模型不是终点。真正可用的会议系统,需要把 ASR、音频处理、文本整理、纪要生成、权限管理和知识检索放在同一条工程链路里考虑。"}]},{"type":"paragraph","attrs":{"id":"0264d0a6-7fb8-4518-b30b-1202f3ee58c8","textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false},"content":[{"type":"text","text":"只有这样,会议转写才不只是一个模型 Demo,而是可以进入日常流程的生产系统。"}]},{"type":"paragraph","attrs":{"id":null,"textAlign":"inherit","indent":0,"color":null,"background":null,"isHoverDragHandle":false}}]}","createTime":1783393477,"ext":{"closeTextLink":0,"comment_ban":0,"description":"","focusRead":0},"favNum":0,"html":"","isOriginal":0,"likeNum":0,

最新游戏

更多

Copyright©2010-2019. All rights reserved | 波波三国游戏官网|[email protected]

备案编号:湘ICP备2022015115号-4