"""处理器能力声明 本模块定义每种处理器的能力,使调用者无需阅读实现代码即可了解: - 支持哪些输入类型(文本/图像/音频) - 支持哪些输出类型(文本/音频) - 支持哪些交互特性(打断/回溯) - 资源占用特性 设计理念: ========= 能力声明是一种"契约",让调用者(Gateway、前端)知道: 1. 某个 Processor 能做什么 2. 不能做什么 3. 需要什么资源 这样 Gateway 可以根据能力进行路由和调度: - 双工请求 → 路由到 Duplex Worker(独占) - 普通请求 → 路由到 Chat Worker(可共享) 使用示例: ========= ```python from core.capabilities import ProcessorMode, CAPABILITIES # 查询某模式的能力 cap = CAPABILITIES[ProcessorMode.DUPLEX] print(f"双工模式支持打断: {cap.supports_interrupt}") # True print(f"双工模式需要独占: {cap.requires_exclusive_worker}") # True # 在 Gateway 中使用 def route_request(request): mode = determine_mode(request) cap = CAPABILITIES[mode] if cap.requires_exclusive_worker: return allocate_exclusive_worker() else: return allocate_shared_worker() ``` 三种模式的能力对比: ================== | 能力 | Chat | Half-Duplex | Duplex | |------|------|-------------|--------| | 文本输入 | ✅ | ✅ | ✅ | | 图像输入 | ✅ | ✅ | ✅ | | 音频输入 | ✅ | ✅ | ✅ | | 文本输出 | ✅ | ✅ | ✅ | | 音频输出 (TTS) | ✅ | ✅ | ✅ | | 流式输出 | ❌ | ✅ | ✅ | | 多轮对话 | ✅ | ✅ | ✅ | | 打断支持 | ❌ | ❌ | ✅ | | 回溯支持 | ✅ | ✅ | ❌ | | KV Cache 复用 | ✅ | ✅ | ❌ | | 独占 Worker | ❌ | ❌ | ✅ | """ from dataclasses import dataclass from enum import Enum, auto from typing import Dict class ProcessorMode(Enum): """处理器模式 MiniCPMO45 支持三种处理模式,每种模式有不同的特性。 - CHAT: 单工对话 - 一问一答,同步等待完整响应 - 适合简单问答、批量处理 - 使用 MiniCPMO 类 - HALF_DUPLEX: 半双工对话 - 一问一答,流式返回响应 - 独占 Worker,支持 VAD 语音检测 - 使用 MiniCPMO 类(streaming=True) - DUPLEX: 双工对话 - 全双工,用户和模型可同时说话 - 适合语音助手、实时交互 - 使用 MiniCPMODuplex 类(不同的类!) **[CRITICAL] CHAT/STREAMING vs DUPLEX**: - CHAT 和 STREAMING 使用同一个模型实例(MiniCPMO) - DUPLEX 使用不同的模型类(MiniCPMODuplex) - 切换 CHAT/STREAMING:只需 init_tts(streaming=True/False) - 切换到 DUPLEX:需要重新加载模型 这意味着 Worker 可以分为两类: - MiniCPMO Worker:处理 CHAT 和 STREAMING - MiniCPMODuplex Worker:处理 DUPLEX """ CHAT = auto() HALF_DUPLEX = auto() DUPLEX = auto() @dataclass(frozen=True) class ProcessorCapabilities: """处理器能力声明 定义一个处理器支持的所有能力和特性。 **输入能力**: - supports_text: 支持文本输入 - supports_image: 支持图像输入 - supports_audio: 支持音频输入 - supports_video: 支持视频输入(图像帧序列) **输出能力**: - supports_text_output: 支持文本输出 - supports_audio_output: 支持音频输出(TTS) - supports_streaming_output: 支持流式输出 **交互能力**: - supports_multi_turn: 支持多轮对话 - supports_interrupt: 支持打断(用户打断模型) - supports_rollback: 支持回溯(恢复到之前的状态) **资源特性**: - requires_exclusive_worker: 是否需要独占 Worker - supports_kv_cache_reuse: 是否支持 KV Cache 复用 Attributes: mode: 处理器模式 supports_text: 支持文本输入 supports_image: 支持图像输入 supports_audio: 支持音频输入 supports_video: 支持视频输入 supports_text_output: 支持文本输出 supports_audio_output: 支持音频输出 supports_streaming_output: 支持流式输出 supports_multi_turn: 支持多轮对话 supports_interrupt: 支持打断 supports_rollback: 支持回溯 requires_exclusive_worker: 需要独占 Worker supports_kv_cache_reuse: 支持 KV Cache 复用 """ mode: ProcessorMode # 输入能力 supports_text: bool = True supports_image: bool = True supports_audio: bool = True supports_video: bool = False # 图像帧序列 # 输出能力 supports_text_output: bool = True supports_audio_output: bool = True # TTS supports_streaming_output: bool = False # 交互能力 supports_multi_turn: bool = True supports_interrupt: bool = False # 打断 supports_rollback: bool = False # 回溯 # 资源特性 requires_exclusive_worker: bool = False supports_kv_cache_reuse: bool = True def __str__(self) -> str: """返回能力摘要""" features = [] if self.supports_streaming_output: features.append("streaming") if self.supports_interrupt: features.append("interrupt") if self.supports_rollback: features.append("rollback") if self.requires_exclusive_worker: features.append("exclusive") return f"{self.mode.name}: [{', '.join(features) or 'basic'}]" # ============================================================================= # 预定义能力 # ============================================================================= CHAT_CAPABILITIES = ProcessorCapabilities( mode=ProcessorMode.CHAT, # 输入:全支持 supports_text=True, supports_image=True, supports_audio=True, supports_video=False, # Chat 不支持视频(图像帧序列) # 输出:文本+音频,非流式 supports_text_output=True, supports_audio_output=True, supports_streaming_output=False, # 非流式 # 交互:多轮+回溯 supports_multi_turn=True, supports_interrupt=False, # 不支持打断 supports_rollback=True, # 支持回溯(通过 speculative_snapshot) # 资源:共享、KV Cache 复用 requires_exclusive_worker=False, supports_kv_cache_reuse=True, ) """单工对话能力 特点: - 一问一答,完整返回 - 不支持打断 - 支持回溯(speculative_snapshot) - 可以共享 Worker - 支持 KV Cache 复用(多轮对话) """ HALF_DUPLEX_CAPABILITIES = ProcessorCapabilities( mode=ProcessorMode.HALF_DUPLEX, # 输入:全支持 supports_text=True, supports_image=True, supports_audio=True, supports_video=False, # 输出:文本+音频,流式 supports_text_output=True, supports_audio_output=True, supports_streaming_output=True, # 交互:多轮+回溯 supports_multi_turn=True, supports_interrupt=False, supports_rollback=True, # 资源:独占 Worker requires_exclusive_worker=True, supports_kv_cache_reuse=True, ) """半双工对话能力 特点: - 半双工语音通话(VAD 检测语音 → 模型推理 → 流式返回) - 独占 Worker(会话期间) - 支持回溯(speculative_snapshot) - 支持 KV Cache 复用 """ DUPLEX_CAPABILITIES = ProcessorCapabilities( mode=ProcessorMode.DUPLEX, # 输入:全支持,包括视频 supports_text=True, supports_image=True, supports_audio=True, supports_video=True, # 支持视频(图像帧序列)! # 输出:文本+音频,流式 supports_text_output=True, supports_audio_output=True, supports_streaming_output=True, # 交互:多轮+打断 supports_multi_turn=True, supports_interrupt=True, # 支持打断! supports_rollback=False, # 不支持回溯 # 资源:独占! requires_exclusive_worker=True, # 独占! supports_kv_cache_reuse=False, # 不复用 ) """双工对话能力 特点: - 全双工,用户和模型可同时说话 - 支持打断(用户打断模型) - 支持视频输入(图像帧序列) - 需要独占 Worker(实时性要求) - 不支持 KV Cache 复用(状态复杂) """ # 能力字典(按模式索引) CAPABILITIES: Dict[ProcessorMode, ProcessorCapabilities] = { ProcessorMode.CHAT: CHAT_CAPABILITIES, ProcessorMode.HALF_DUPLEX: HALF_DUPLEX_CAPABILITIES, ProcessorMode.DUPLEX: DUPLEX_CAPABILITIES, } """按模式索引的能力字典 使用示例: >>> from core.capabilities import CAPABILITIES, ProcessorMode >>> cap = CAPABILITIES[ProcessorMode.DUPLEX] >>> cap.supports_interrupt True """ def get_capabilities(mode: ProcessorMode) -> ProcessorCapabilities: """获取指定模式的能力声明 Args: mode: 处理器模式 Returns: 对应模式的能力声明 Raises: KeyError: 未知的模式 示例: >>> cap = get_capabilities(ProcessorMode.CHAT) >>> print(cap) CHAT: [rollback] """ return CAPABILITIES[mode] def supports_feature(mode: ProcessorMode, feature: str) -> bool: """检查指定模式是否支持某特性 Args: mode: 处理器模式 feature: 特性名称(如 "interrupt", "rollback", "streaming_output") Returns: 是否支持该特性 Raises: AttributeError: 特性名称不存在 示例: >>> supports_feature(ProcessorMode.DUPLEX, "interrupt") True >>> supports_feature(ProcessorMode.CHAT, "interrupt") False """ cap = CAPABILITIES[mode] attr_name = f"supports_{feature}" if hasattr(cap, attr_name): return getattr(cap, attr_name) raise AttributeError(f"Unknown feature: {feature}")