Voice Identity:建立 Independent ASR 生产基础链路 - #2450
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (3)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
基础链路收敛验证(2026-07-23)
边界保持:Draft;无阈值、无拦截、无 UI/API、无持久化、无 Omni、无攻击防御、无 Provider/SmartTurn/RNNoise/Silero 行为修改。 |
#2450 基础链路收敛验证(head
|
06e74f2 to
3835e68
Compare
补充:当前基础声纹链路的运行语义(head
|
cae2e80 to
c07e05c
Compare
|
已完成 rebase 并解决冲突:
|
c07e05c to
ed13288
Compare
ed13288 to
85a54b3
Compare
|
已完成本轮 rebase 并解决冲突:
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85a54b3668
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| item_id = event.get("item_id") | ||
| if isinstance(item_id, str): | ||
| item_keys.pop(item_id, None) | ||
| await _emit_error( |
There was a problem hiding this comment.
Ignore stale OpenAI failure events
When OpenAI sends a conversation.item.input_audio_transcription.failed for an item that was already cleared or belongs to an old route epoch, item_keys.pop(item_id, None) returns None, but the worker still emits ASR_OPENAI_TRANSCRIPTION_FAILED and exits. This differs from completed/delta handling, where unknown item IDs are ignored, so a late failure after clear/barge-in can unnecessarily kill an otherwise healthy ASR worker.
Useful? React with 👍 / 👎.
| if runtime is not None: | ||
| self._runtimes.add(runtime) |
There was a problem hiding this comment.
Avoid requiring weak-refable verifier runtimes
For a custom SpeakerVerifierRuntime implemented with __slots__ or as an unhashable dataclass, this WeakSet.add() raises TypeError even though the object satisfies the verifier protocol, causing profile activation/reconciliation to fail as soon as the runtime is created. Since the contract does not require weak-reference support, the session should not impose it implicitly.
Useful? React with 👍 / 👎.
目标
在 #2408 的真实 CAM++ Shadow 之上收敛 provider-neutral 的生产基础链路,只打通:
固定测试 PCM → 真实 CAM++ enrollment → 内存 profile → Core 正式内部入口 → IndependentAsrRuntime → Detector candidate → 真实 CAM++ 评分 → 无执行权 observer → similarity observation → disable/close 清理。
本 PR 是 stacked Draft,base 仍为 #2408 分支。#2398 / #2408 尚未合并前不转 Ready,也不请求正式 Review。
本轮收敛
set_speaker_identity_observer(callback | None)端口;测试不再修改 Core 的 callback 私有字段。set_active_speaker_profile(profile | None)明确返回 profile revision 或None;CAM++ model ID、revision、192 维、finite 与 L2 合同会在激活时立即校验。wait_closed()受控关闭合同,同时保留普通close()的快速返回/延后清理语义。真实完整链路证据
新增固定合成 PCM 的 process-level smoke,不提交 PCM、embedding 或模型权重:
CampPlusEmbeddingModel → build_campplus_speaker_profile → Core.set_active_speaker_profile → Core.set_speaker_identity_observer → IndependentAsrRuntime → DetectorRuntime → SpeakerShadowRuntime → CampPlusSpeakerShadowBackend → observation验证结果:
1.0(相同固定合成输入,仅证明链路,不代表准确率)。Provider / 生命周期隔离
固定不可变输入按
baseline → identity → identity → baseline重放,并比较:上述合同一致;不比较 callback chunk 数量。profile 快速更新、ASR route rebuild、清理失败/超时、Detector reset/close、observer 更换与失败均有受控竞态测试。
Regression Report
249 passed。648 passed, 2 skipped。git diff --check:通过。结构合同
voice_identity不反向依赖 Core、Provider worker、transport 或 UI。voice_identity.campplus。voice_identity.contracts。voice_identity依赖图无环。CampPlusEmbeddingModel和一处模型专属 ONNX session 创建实现。asr_client/campplus.py兼容 facade 已删除。asr_client/speaker_shadow.py只拥有 ASR candidate identity;SpeakerShadowConfig、SpeakerShadowObservation、SpeakerShadowRuntime继续归voice_identity。明确不包含
停止点
本 PR 到“正式 Independent ASR 运行时可显式接收内存声纹,使用真实 CAM++ 对候选音频评分,并通过无执行权 observer 输出结果;profile 更新和 ASR route rebuild 时最多一个 ONNX session,且不影响 Provider/ASR”即停止扩展。
这仍不是面向用户的声纹安全功能,也不执行任何拦截。