尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Friend 开源项目 Parakeet ASR GPU 服务实战指南:自托管双模型语音转文字(批处理 + 流式 + 说话人分离)

发布时间:2026/9/15 11:45:32

资讯中心
01
ARTICLE

Friend 开源项目 Parakeet ASR GPU 服务实战指南:自托管双模型语音转文字(批处理 + 流式 + 说话人分离)

Friend 开源项目 Parakeet ASR GPU 服务实战指南:自托管双模型语音转文字(批处理 + 流式 + 说话人分离)
Friend 开源项目 Parakeet ASR GPU 服务实战指南自托管双模型语音转文字批处理 流式 说话人分离【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend本文以开源项目 Friend 的 backend/parakeet/README.md 为骨架结合仓库内全套源码与部署配置完整讲解自托管 NVIDIA Parakeet 语音识别服务的架构、HTTP/WebSocket API、全部环境变量、动态批处理与流式管线原理以及基于 Helm 的 GKE GPU 部署方案。读完本文你将掌握如何调用该服务完成带标点与时间戳的批量转写、端到端说话人分离、实时流式识别并理解其底层实现与调优参数。服务定位与双模型架构Parakeet ASR GPU Service 是 Friend 后端中自托管的语音转文字Speech-to-Text子系统运行在 GKE GPU 节点池上通过内部负载均衡器Internal Load Balancer对外暴露供 backend-listen 等下游服务消费。整个服务围绕两套 NVIDIA Parakeet 模型构建模型规模用途特点nvidia/parakeet-tdt-0.6b-v30.6BTDT批量转写v1/v2全标点、大小写、精确时间戳README 标注 WER 约 0.1%nvidia/parakeet-rnnt-1.1b1.1BRNNT流式转写v3分块解码器实时输出无标点小写输出关键设计决策批量与流式推理共享同一个 CUDA 上下文因此 gpu_worker.py 中强制要求当配置了PARAKEET_STREAM_MODEL时PARAKEET_CUDA_GRAPHS必须保持关闭false否则启动即抛ValueError。Dockerfile 注释还提示该镜像栈曾在 L4 GPU 上以 43 RPS 持续吞吐进行过基准测试这一结论来自仓库内 Dockerfile 的构建注释供部署容量规划参考。从 requirements.txt 可以看出项目使用了 beastoin 维护的 NeMo fork带并发推理线程安全修复原因在于上游 NeMo 在并发 GPU 推理下会段错误依赖中还包含 pyannote.audio内置说话人 embedding与 prometheus-client指标暴露。HTTP API 详解服务基于 FastAPI 实现入口为 main.py端口 8080提供四个核心端点。POST /v1/transcribe— 批量转写接收 multipart 音频文件16 kHz 单声道返回 JSON{ text: 完整转写文本含标点与大小写, segments: [ {text: 句子文本, start: 0.0, end: 2.5}, {text: 下一句, start: 2.5, end: 5.1} ] }模型TDT 0.6b支持完整标点、大小写与精确时间戳。实现请求先经 main.py#L189-L239 落盘到_temp/随后提交给BatchEnginetimestampsTrue由 GPU 工作线程执行批推理结果经_transcribe_from_gpu_result序列化回传给客户端。限制当 GPU 模型尚未加载完成时返回503 {detail: Model loading, try again shortly}队列满返回503音频超长返回413见后文PARAKEET_MAX_FILE_DURATION。POST /v2/transcribe— 批量转写 说话人分离与 v1 相同额外提供服务端说话人分离与语言检测表单参数diarizetrue默认开启、num_speakers、min_speakers、max_speakers。返回的每个 segment 额外携带speaker标签SPEAKER_0、SPEAKER_1…与detected_language。说话人分离使用 GPU 上的内置 pyannote/wespeaker embedding 模型pyannote/wespeaker-voxceleb-resnet34-LM无需外部服务。参数校验min_speakers max_speakers或num_speakers与范围参数同时出现都会返回422——这是 main.py#L253-L267 中的显式校验逻辑避免调用方误以为自己的约束被满足。分离算法细节transcribe.py#L269-L439先为每个可嵌入的 segment 提取 embedding时长不足 0.6 秒的 segment 保持SPEAKER_0兜底然后用 scipy 平均连接层次聚类average-linkage AHC在余弦距离上一次性划分全部 embedding使划分结果与 segment 顺序无关聚类完成后按“首次出现顺序”重编号为SPEAKER_N时长过短无法嵌入的 segment 则继承时间上最近的已聚类 segment 的说话人。聚类阈值由PARAKEET_SPEAKER_AHC_THRESHOLD控制默认 0.55代码注释记录该值在 VoxConverse 测试子集上经调优3 说话人 DER 从 0.174 降至 0.130。WS /v3/stream— 流式转写WebSocket建立 WebSocket 连接后持续发送原始 PCM16 音频块服务端实时回推 JSON segment{type: ready, ...} // 连接建立后服务端先回 ready {text: ..., start: 0.0, end: 1.2, speaker: SPEAKER_0, detected_language: en}模型RNNT 1.1b采用分块解码器2 秒 chunk 10 秒左侧上下文另有 2 秒右侧上下文见 stream_handler.py#L73。VAD 端点检测Silero VAD语音结束挂起hangover后切分 utterance最长连续语音 5 秒强制发射生产配置PARAKEET_MAX_SPEECH_S5。AGC 归一化针对 BLE 麦克风低音量音频将每个 512 采样块归一化到目标峰值PARAKEET_AGC_TARGET默认 0.8见_normalize_pcm16stream_handler.py#L415-L425。内置说话人分离基于 embedding 余弦距离的在线质心聚类质心随新 embedding 滚动平均最多PARAKEET_SPEAKER_CLUSTERING_MAX_SPEAKERS个默认 8见 speaker_math.py。查询参数sample_rate默认 16000、vad_threshold、hangover_s覆盖服务端默认值。会话终止发送文本finalize服务端 flush 剩余语音后关闭连接30 秒无消息不超时断开_WS_RECEIVE_TIMEOUT仅用于 keep-alive 轮询。已知限制RNNT 流式输出不带标点小写输出。流式管线细节stream_handler.py#L372-L493每个StreamSession维护左/中/右上下文窗口RNNT 解码器状态跨 chunk 保持VAD 只负责决定何时把最新解码文本增量发射为 segment。服务启动时会通过warmup_rnnt_decoder()跑一个哑 chunk 预编译 CUDA 内核消除首个真实连接 15–20 秒的冷启动延迟stream_handler.py#L116-L149。如果 RNNT 流式解码遇到非致命错误会话会自动回退到“VAD 切分 批模型转写”路径保证可用性。GET /health— 健康检查状态HTTP 码响应体模型就绪200{status: healthy, ready: true, uptime_seconds: ...}模型加载中503{status: loading, ready: false}致命 CUDA 错误503{status: unhealthy, ready: false, reason: ...}Kubernetes 的 readiness、liveness、startup 三种探针都指向该端点main.py#L415-L430。reason字段来自GPUWorker.classify_fatal_cuda_error对 CUDA 错误消息的分类device_side_assert、illegal_memory_access、launch_failure、stream_capture、accelerator_error等见 gpu_worker.py#L58-L72。GET /batch/metrics— 批引擎统计返回动态批处理引擎的内部计数{ total_requests: 0, total_batches: 0, total_files: 0, rejected_requests: 0, pending_requests: 0, vram_limited_batches: 0 }环境变量与配置参数全表以下参数均通过环境变量注入默认值与 README 及源码读取逻辑一致。批模型与 GPU Worker变量默认值作用PARAKEET_MODELnvidia/parakeet-tdt-0.6b-v3批量模型PARAKEET_DEVICEcuda:0批量推理 GPU 设备PARAKEET_TORCH_COMPILEtrue启用 torch.compile内核融合带来约 20–30% 吞吐README 声明PARAKEET_CUDA_GRAPHSfalse启用 CUDA graph 解码配置了PARAKEET_STREAM_MODEL时必须保持关闭共享 CUDA 上下文PARAKEET_GC_INTERVAL50每 N 个批次执行一次完整gc.collect()每批执行gc.collect(0)PARAKEET_GPU_POLL_TIMEOUT0.05GPU worker 队列轮询间隔秒PARAKEET_BF161BF16 模型加载GPU 显存减半PARAKEET_ATTENTION_MODEfull注意力模式full/local线性显存缩放/auto超阈值自动切换源码在 gpu_worker.py#L114-L120 校验取值PARAKEET_AUTO_ATTN_THRESHOLD300auto模式下切换 local 注意力的时长阈值秒PARAKEET_LOCAL_ATTN_CONTEXT128,128local 注意力上下文左,右PARAKEET_MAX_FILE_DURATION0不限制单文件最大时长秒数超限返回 413PARAKEET_VRAM_SAFETY_FACTOR0.8VRAM 感知批处理的安全系数见下文PARAKEET_VRAM_BYTES_PER_T2136.6每 token 平方的显存系数MB用于估算 batch 上限PARAKEET_STARVATION_TIMEOUT5.0排队超过该秒数的请求优先组批防饿死PARAKEET_MAX_INFLIGHT2同时在途 GPU 批数信号量控制动态批处理变量默认值作用PARAKEET_MAX_BATCH_SIZE32每 GPU 批最多文件数PARAKEET_BATCH_WAIT_SECONDS0.002定时器刷新间隔秒用于组装不满批PARAKEET_MAX_QUEUE_DEPTH4096背压上限超过返回 503流式变量默认值作用PARAKEET_STREAM_MODEL必填流式模型RNNT 1.1bPARAKEET_MAX_SPEECH_S30最长语音时长超过强制发射生产配置为 5PARAKEET_AGC_TARGET0.8AGC 归一化目标峰值PARAKEET_VAD_THRESHOLD0.5Silero VAD 语音概率阈值PARAKEET_CHUNK_S2.0RNNT chunk 大小秒PARAKEET_LEFT_CONTEXT_S10.0RNNT 左侧上下文秒PARAKEET_RIGHT_CONTEXT_S2.0RNNT 右侧上下文秒源码补充PARAKEET_MIN_SPEECH_S0.5最短语音时长更短则丢弃源码补充PARAKEET_HANGOVER_S0.8VAD 语音结束挂起秒数源码补充PARAKEET_STREAM_CAPACITY必填单 Pod 并发流硬上限PARAKEET_STREAM_ALLOCATION_PERCENT必填流量分配百分比0–100用于灰度放量PARAKEET_SPEAKER_CLUSTERING_THRESHOLD0.60在线说话人质心聚类余弦距离阈值speaker_math.pyPARAKEET_SPEAKER_CLUSTERING_MAX_SPEAKERS8在线聚类最大说话人数speaker_math.pyPARAKEET_SPEAKER_AHC_THRESHOLD0.55离线批处理 AHC 聚类距离阈值transcribe.py#L220其他变量默认值作用PARAKEET_INFERENCE_MODEnemo推理后端nemo自托管 NeMo或nimNVIDIA NIMNIM_INFERENCE_URLhttp://localhost:9000NIM 模式下的推理端点源码补充NIM_LANGUAGEmultiNIM 转写的语言参数源码补充HOSTED_SPEAKER_EMBEDDING_API_URL空外部 diarizer 后备 embedding 服务可选内置优先HUGGINGFACE_TOKEN下载 pyannote 说话人 embedding 模型所需 token源码级原理动态批处理与 VRAM 感知批量请求并非逐个推理而是由 batch_engine.py 中的BatchEngine攒批执行。核心机制攒批与定时刷新请求进入_pending队列每当队列长度达到min(PARAKEET_MAX_BATCH_SIZE, vram_limit)即立即触发 flush否则由_flush_loop每PARAKEET_BATCH_WAIT_SECONDS默认 2ms轮询刷新不满批。VRAM 感知组批_estimate_max_batch根据音频时长 T 估算每文件显存占用vram_bytes_per_t2 * T² / 0.08²即注意力随 token 数平方增长结合PARAKEET_VRAM_SAFETY_FACTOR与基线显存算出每批预算。attention_modelocal时注意力线性缩放不受该限制auto模式下超过PARAKEET_AUTO_ATTN_THRESHOLD默认 300s的长音频改用 local 注意力。_form_vram_safe_batch还会优先捞起排队超过PARAKEET_STARVATION_TIMEOUT的“饥饿”请求防止长音频被短音频无限挤压。在途控制PARAKEET_MAX_INFLIGHT默认 2信号量限制同时提交给 GPU 的批数防止 OOM触发 OOM 时通过回调递增parakeet_gpu_oom_total指标。背压队列深度达到PARAKEET_MAX_QUEUE_DEPTH4096时抛QueueFullError上层返回 503{detail: Server overloaded — try again later}。GPU 侧由 gpu_worker.py 的GPUWorker守护线程消费队列。该线程在启动时加载批量模型加载过程依次执行cudnn.benchmarkTrue、float32 matmul precisionhigh、BF16 转换、可选 torch.compile、CUDA graph 禁用、注意力模式切换最后加载 pyannote embedding 模型并记录 VRAM 基线_vram_total_mb/_vram_baseline_mb。所有推理在torch.inference_mode()下执行并周期性执行gc.collect(0)。若推理抛出的 CUDA 错误被classify_fatal_cuda_error判定为破坏 CUDA 状态的致命错误worker 会清空队列、置fatal_cuda_reason并停止服务——这正是/health返回unhealthy的机制。说话人分离的两种实现路径仓库中说话人分离有两条实现离线v2 批量先 ASR 得到 segment再对每个可嵌入 segment 提取 embedding用 scipy 平均连接 AHC 一次性聚类整文件按首次出现顺序重编号SPEAKER_0/N短 segment 按时间最近继承说话人。优点是划分与顺序无关鲁棒。在线v3 流式每个 utterance 计算 embedding与已有质心计算余弦距离小于阈值则并入最近质心并滚动平均达到PARAKEET_SPEAKER_CLUSTERING_MAX_SPEAKERS上限后强制并入最近质心此时第四个返回值cappedTrue供日志观测且该次 miss 不污染质心均值见 speaker_math.py#L22-L52。短于 0.6 秒的音频直接沿用上一个说话人。两条路径都优先使用 GPU 内置的 wespeaker embedding通过GPUWorker.submit_embedding_sync提交未安装或未就绪时才回退到HOSTED_SPEAKER_EMBEDDING_API_URL指向的外部 diarizer 服务生产配置指向prod-omi-diarizer集群内服务。部署镜像构建与 Helm 上生产镜像构建Dockerfile 基于nvcr.io/nvidia/nemo:26.02内置 PyTorch 2.6 CUDA 12.8 NeMo 2.3在其上叠加 beastoin NeMo fork、torchaudio2.5.1兼容层、pyannote.audio 3.3.2 及一组 stubtorch_audiomentations、telemetry最后COPY backend/parakeet/与测试目录。容器暴露 8080内置/health的HEALTHCHECKstart-period 180s以uvicorn main:app --loop uvloop启动。构建命令仓库注释提供docker build -f backend/parakeet/Dockerfile -t parakeet-batch .另有 Dockerfile.nim 对应PARAKEET_INFERENCE_MODEnim的 NIM 推理后端形态此时服务仅作为 NIM 端点代理不加载本地模型见 main.py#L160-L161。Helm 部署README 给出的安装命令helm upgrade --install parakeet ./backend/charts/parakeet \ -f ./backend/charts/parakeet/prod_omi_parakeet_values.yaml \ --namespace prod-omi-backend生产 valuesprod_omi_parakeet_values.yaml要点资源request2 CPU / 8Gi / 1 GPUlimit3 CPU / 20Gi / 1 GPU。探针readinessfailureThreshold1、livenessfailureThreshold3、startupfailureThreshold60最多 600 秒等待模型加载全部命中/health。网络ClusterIP Service8080 GCE Internal Ingressgce-internal仅暴露/v1/transcribe、/v2/transcribe、/v3/stream、/health四个路径README 明确指出服务无需鉴权因为只运行在内部 LB 之后。密钥HUGGINGFACE_TOKEN、ENCRYPTION_SECRET从prod-omi-backend-secretsSecret 注入。生产关键参数PARAKEET_STREAM_CAPACITY25每 Pod 25 路并发流、PARAKEET_MAX_SPEECH_S5、PARAKEET_ATTENTION_MODEauto、PARAKEET_MAX_FILE_DURATION3600、PARAKEET_VRAM_SAFETY_FACTOR0.8。HPA 自动扩缩基于requestsPerPod20与targetGPUUtilization70min/max 1/2带 scale up/down 稳定窗口与速率策略chart 的 hpa.yaml 与 values 中的autoscaling段。调度亲和节点亲和要求serviceparakeet、envprod标签。后端消费方通过集群内服务地址HOSTED_PARAKEET_API_URL连接本服务无外部暴露。与流式准入配合的是 admission.py 的StreamAdmissionController每个 GPU Pod 进程内维护硬容量PARAKEET_STREAM_CAPACITY与流量分配百分比PARAKEET_STREAM_ALLOCATION_PERCENT后者用于灰度放量小于 100 时按概率拒绝allocation_rejected。由于 Parakeet chart 每个 GPU Pod 只跑一个 Uvicorn worker进程本地边界即 Pod 容量边界。可观测性Prometheus 指标与自动扩缩服务在/metrics挂载 Prometheus ASGI 端点main.py#L173-L174chart 同时提供 metrics Service9091与 ServiceMonitorrelease: prod-omi-kube-prometheus-stack15s 采集间隔。仓库 main.py#L43-L86 定义的指标包括指标类型含义parakeet_active_streamsGauge活跃 WebSocket 流数parakeet_active_batch_requestsGauge活跃批量请求数parakeet_batch_pending_requestsGauge批引擎排队请求数parakeet_request_duration_secondsHistogram各端点请求延迟parakeet_stream_duration_secondsHistogram流会话时长parakeet_batch_sizeHistogram每 GPU 批文件数parakeet_rtfxGauge最近请求实时因子音频时长/处理时长parakeet_gpu_oom_totalCounterCUDA 显存溢出事件parakeet_gpu_fatal_errors_totalCounter致命 CUDA 错误次数parakeet_requests_totalCounter按端点/状态统计的请求数这些指标不仅用于 Dashboard还通过 prometheus-adapter 规则驱动 HPArequests-per-pod、GPU 利用率。由于 metrics 采集线程与 GPU 推理线程隔离GPU worker 崩溃不会阻断指标上报。运维要点与故障排查模型加载慢TDT 0.6b 与 RNNT 1.1b 双模型加载可能耗时数分钟startupProbe 允许最长 600 秒/health在就绪前持续返回 503loading此阶段到达的请求会被快速拒绝而非排队。致命 CUDA 错误一旦发生 device-side assert 或非法内存访问worker 停止处理并记录reason/health返回 503unhealthy此时应重建 Pod滚动更新策略maxUnavailable: 1, maxSurge: 0保证单副本安全替换。流式无标点RNNT 流式输出为小写无标点需要标点场景应改用 v1/v2 批量端点。说话人分离降级未安装 pyannote 或未配置 embedding 服务时v2 与 v3 的 segment 统一标记为SPEAKER_0代码显式兜底日志会给出 warning。长音频支持默认 full 注意力下显存随时长平方增长超长文件应设置PARAKEET_ATTENTION_MODElocal或auto并通过PARAKEET_MAX_FILE_DURATION设置硬上限超限返回 413 并附说明。背压信号队列满返回 503客户端应实现重试与退避/batch/metrics的rejected_requests与pending_requests可直接用于监控负载。通过本指南你可以在 Friend 项目中完成 Parakeet ASR 服务的调用、参数调优与生产部署并结合源码理解批处理、流式、说话人分离三大能力的底层实现。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。