文档

开始使用

novme 是什么?

听懂当下,带走一份完整记录。

novme 是一款面向 macOS 的会议字幕与复盘工具。它同时采集本机麦克风和指定会议应用的音频, 优先发布源语言字幕,再异步补充中英文翻译;会议结束后,它会保留完整逐字稿并生成摘要、决策、 行动项和风险。

  • 低延迟:源字幕先显示,翻译不会阻塞下一条源字幕。
  • 双路采集:区分“我”和“会议”两类音频来源,关键帧带有可追踪的序号与时间信息。
  • 完整复盘:实时路径可以降级或延后,但会议资料会持久化并在结束阶段补齐。
  • 两种推理方式:支持 Apple Silicon 本地 MLX,也支持通过 Bearer 认证连接 DGX Spark。

从声音到会议记录

novme 将“实时可读”和“会后完整”拆成两条策略不同的处理路径。

其他

版本与更新

当前发布:novme 0.1.40(构建 99)。修复旧版服务端尚未支持整理进度接口时的重复请求和日志噪音。

当前版本0.1.40 (99)
更新方式客户端启动时自动检查,也可以在 macOS 设置中手动检查
安全校验下载大小、SHA-256、应用标识与 Developer ID 签名

会议结束进度兼容性修复

  • 服务端支持时,结束会议会显示真实的分阶段整理进度。
  • 连接旧版服务端时,客户端会记录一次兼容性诊断并停止轮询,不影响会议结束和最终总结。
  • 保留音频归档、逐字稿、说话人归属、会议总结与重试的原有可靠性保护。

快速开始

首次使用本地模式

在 macOS 设置的“服务”页选择本地模式,novme 会统一下载、校验、启动和预热所选运行组件。模型缺失或预热失败时,novme 会直接显示错误,不会静默切换到远端。

环境要求

系统macOS 13 或更新版本
本地推理Apple Silicon;运行组件按需下载并校验签名
客户端正式发布包不要求 Python、pip 或 Swift 工具链

首次安装:3 步完成本地配置

01

选择本地模型

打开 App 的 macOS“设置 → 服务”,选择“本地”,分别选择 ASR、实时翻译和会议总结模型。已校验的模型会被跳过,未完成的模型会进入同一次准备流程。

02

下载并启动

点击“启动并使用”。novme 会下载缺失运行组件和模型、校验 SHA-256、启动本地 MLX 并执行真实预热;状态变为“本地推理已就绪”前不要开始会议。

03

自动连接本地后端

准备成功后,客户端自动使用 http://127.0.0.1:18080 和“直连”路由,API Key 留空,并重新检查严格健康契约。状态可用后即可开始会议。

授予系统权限

  1. 允许 novme 使用麦克风。
  2. 允许 novme 进行屏幕录制,以便 ScreenCaptureKit 读取会议应用音频。
  3. 授权后完全退出并重新打开 novme。

从源码运行(开发者)

Terminal
./script/build_and_run.sh --verify

正式发布包不需要执行此命令。仓库开发者使用验证模式检查应用签名、启动状态和权限连续性;普通重建不应重置系统权限。

novme 原生 macOS 会议设置界面
设置阶段只保留开始会议所需的来源、语言和后端状态。

开始使用

连接与认证

novme 没有用户名、密码、Cookie 或 OAuth 登录。连接身份是后端共享的 API Key,原生客户端会把它作为 Bearer 凭证发送给 HTTP 和 WebSocket。

本地后端

下载并校验签名后的本地 MLX 后端只监听 http://127.0.0.1:18080。在“设置 → 服务”选择本地并点击“启动并使用”后,客户端会自动保存该地址、选择“直连”并清空 API Key;严格健康检查通过后才允许开始会议。

远端 Spark

原生客户端不预置远端地址;在“设置 → 服务”选择远程后,输入明确的后端原点和 Bearer API Key。远端的 FastAPI 对外提供统一 HTTP/WebSocket 入口,Spark 的 llama-server 和可选 MiMo 服务仍只监听远端回环地址。

在程序中保存连接

  1. 打开 macOS“设置”(Command-,),进入“连接”页。
  2. 填写后端原点地址和 API Key,地址只能包含协议、主机和端口,不能附带路径、查询参数或内嵌账号密码。
  3. 点击“保存并检查”。客户端先校验格式,再请求 GET /health;严格模式、模型身份和音频契约不匹配时会显示失败。
  • 后端地址保存在 macOS 应用偏好设置中。
  • API Key 只保存在 Keychain,不写入应用偏好设置;网络请求使用 Authorization: Bearer <API Key>
  • HTTP 与两个 WebSocket 路由共用同一个 Key。缺少或错误的 HTTP 凭证返回 401;WebSocket 会在握手阶段被拒绝。
  • 远端使用明文 HTTP 时,程序会在保存前显示风险警告,因为 Bearer Key、音频、字幕和会议数据都没有传输加密。当前直连只适合可信网络,不能视为 TLS 登录方案。

使用指南

一次会议的三个阶段

novme 把界面收敛为设置、实时字幕和会议复盘,字幕模式结束即回到设置,会议模式可选择是否生成总结。

01

设置

选择字幕或会议模式、会议应用和目标语言。源语言自动识别,麦克风屏蔽与说话人显示采用模式默认值。

02

实时字幕

阅读源字幕和翻译,观察“我 / 会议”两路活动状态,并随时显式结束会议。

03

会议复盘

等待最终处理完成,查看摘要和逐字稿,导出 Markdown,或开始一场新会议。

novme 原生 macOS 会议模式实时字幕界面
会议模式保留最近五条字幕、两路音频状态和结束操作,方便跟随讨论上下文。

核心能力

实时翻译字幕

每个音频帧先归档,再进入识别。源文本先到达客户端,翻译随后更新同一个字幕段。

源字幕优先

翻译任务具有独立的并发与排队边界。翻译繁忙或失败时,源字幕仍然保留并继续发布; 系统会发送 translation_delayedtranslation_error 事件,并在会议结束阶段重试。

音频帧协商

运行配置客户端帧后端处理
固定兼容模式1000 ms每个固定帧形成一个实时推理单元
当前 Spark 自适应 VAD80 ms常规边界为 800 ms 静音 / 15 秒硬上限;语音超过 4 秒后,出现 160 ms 低于来源阈值 75% 的停顿即可提前释放
历史 400 ms / 4 秒方案80 ms仅保留客户端兼容和反例验证;真实回放出现切句、请求/算力放大与无效翻译,不再作为生产部署配置

客户端必须以 GET /health 返回的 client_audio_chunk_ms 为准,不应硬编码帧长。

上传滑动窗口也随帧长缩放:1000 ms 模式允许 4 帧在途,80 ms 模式允许 50 帧在途, 始终保留 4000 ms 的合计来源音频预算。每帧仍使用精确的 (source, seq) 归档确认与重试语义。

页面中的“转写”只表示 ASR 排队加模型执行,不是用户从开口到看到字幕的总延迟。当前本地配置还要等待至少约 1000 ms 语音段形成,并通常等待 800 ms 静音边界;超过 4 秒后才启用 160 ms 软边界。排查慢速时应同时查看 asr_queue_msasr_msaudio_end_to_source_ms 和 utterance 的 duration_ms,不能只看界面上的一个数字。

novme 原生 macOS 会议模式实时字幕界面
会议模式保持五条字幕上下文;实时阶段仍可显式置顶窗口,不改变字幕内容。

背压与完整性

客户端上传和后端推理是两条独立的背压边界。客户端会保留已采集帧,直到收到服务端 archived 确认;如果上传长期追不上双路采集,客户端会显示积压错误并提前停止采集, 保护已经连续归档的会议记录,而不是静默丢弃新音频。后端每个音频来源的实时识别任务和翻译任务 也有明确上限,超出实时推理容量的内容会转为会后处理。

核心能力

会议复盘

结束会议不是立即清空现场,而是进入可见的收尾阶段,等待已接收音频和待处理任务完成。

复盘内容

  • 按时间排序的源语言逐字稿与翻译。
  • 最终说话人标签,并可在复盘页全局改名后同步全文档。
  • 会议摘要、按说话人整理的详细内容、决策、行动项和风险(有结果时显示)。
  • 由后端记录生成的 Markdown 导出文件。
novme 原生 macOS 正在生成会议记录界面
结束后进入可见的生成阶段,已有逐字稿继续保留,摘要和导出动作暂不出现。
novme 原生 macOS 会议复盘界面
成功复盘默认显示摘要,并允许切换到逐字稿或导出记录。

失败时保留什么

摘要或最终处理失败时,界面保留已经存在的逐字稿,并允许对同一个会议 ID 重试。 novme 不会静默创建替代会议,也不会自动返回设置页掩盖失败。

novme 原生 macOS 会议复盘失败界面
复盘失败时保留逐字稿,并把重试和新会议作为明确操作。

核心能力

音频采集

原生客户端分别管理麦克风与会议应用音频,任何来源的异常都必须可见且可追踪。

麦克风

使用 AVAudioEngine 采集本机输入,并在设置和实时阶段显示音量活动。

会议应用音频

macOS 13+ 使用 ScreenCaptureKit 读取用户明确选择的会议应用。 如果选中的应用退出,客户端会显示失败,不会自动换成另一个应用。

开发与部署

后端 API

FastAPI 后端同时提供会议生命周期 REST 接口和实时音频、字幕 WebSocket。

REST

GET/health严格运行身份、引擎、模型与音频帧契约
POST/meetings创建会议并设置源语言与目标语言
POST/meetings/{id}/finish等待接收屏障并完成复盘
GET/meetings/{id}/segments读取最终字幕段
GET/meetings/{id}/summary读取或生成会议摘要
PATCH/meetings/{id}/speakers全局替换会议中的说话人名称
GET/meetings/{id}/export.md导出后端拥有的 Markdown 记录

创建会议

HTTP
POST /meetings
Content-Type: application/json

{
  "source_lang": "auto",
  "target_lang": "zh"
}

WebSocket

路径方向用途
/ws/audio双向客户端发送带来源、序号和时间信息的 PCM 音频帧;后端返回 archiveddeferrederror 状态
/ws/subtitles/{id}后端 → 客户端接收源字幕、翻译更新和类型化状态事件

真实实现

后端处理顺序与有效优先级

novme 没有一个统一的数字优先级队列。当前“优先级”由持久化顺序、每来源串行 ASR、 独立翻译信号量和结束屏障共同形成。

一帧音频的实际处理顺序

顺序实现行为失败或拥塞时
1解码 PCM,追加到会议音频归档;有序客户端还会写入 SQLite audio_chunks 与连续序号。未完成持久化就不发送 archived;错误直接返回给客户端。
2固定模式直接形成推理单元;VAD 模式按 /health 的完整 tuple,把 80 ms 帧按 RMS 组装成至少 1 秒、最多 4 秒或 15 秒的语音段。纯静音段标记完成但不创建字幕;格式、时间线或混合边界 tuple 错误直接失败。
3ASR 按 (meeting_id, source) 串行执行,同一来源保持输入顺序。每来源最多积压 4 个任务;达到上限后转入会后恢复,不无限排队。
4ASR 结果先写入数据库并立即发布源字幕。ASR 失败时保留已归档音频,发送错误并留给结束阶段重跑。
5翻译作为独立任务提交,完成后更新同一个 segment_id 并再次发布。队列满发送 translation_delayed;提供方失败发送 translation_error,源字幕不回滚。

当前队列与并发参数

控制项当前值作用范围
AudioUploadPolicy.inFlightAudioBudgetMs4000 ms原生客户端合计来源音频预算;1000 ms 为 4 帧,80 ms 为 50 帧。
pendingAudioStopThreshold / HardLimit48 s / 60 s原生客户端合计来源音频缓存;80 ms 模式对应 600 / 750 帧,双路采集的墙钟时长约为一半。
NOVME_REALTIME_MAX_PENDING_PER_SOURCE4每个会议、每个音频来源独立计算;同一来源 ASR 串行,麦克风与会议音频可以并行。
NOVME_TRANSLATION_MAX_CONCURRENCY10整个后端进程共享的翻译提供方并发信号量,与 Spark 的 10 个模型槽对齐。
NOVME_TRANSLATION_MAX_PENDING32整个进程中尚未完成的翻译任务总数,不按会议预留配额。
FINISH_BARRIER_TIMEOUT_SECONDS15一次结束请求等待接收、实时 ASR 与翻译收敛的总时限。

翻译和会后总结谁优先

对同一场会议,代码保证的有效顺序如下:

  1. 已确认音频接收:等待客户端上报的最后序号全部进入持久化序列。
  2. 实时工作收敛:等待已登记的音频接收、ASR 和翻译任务。
  3. 补齐翻译:扫描所有有源文本但无译文的字幕段并重新提交翻译。
  4. 翻译硬门禁:仍有缺失译文时,finish 返回 HTTP 502,不生成成功复盘。
  5. 会后处理:重跑延后 ASR、重建顺序音频、执行说话人处理,然后调用总结模型。
  6. 提交最终状态:先保存 summary,再把会议标记为 finalized

翻译请求细节

  • 只翻译当前字幕段,并带上同一音频来源之前最多 2 条字幕作为术语与指代上下文。
  • Spark 请求发送到 /v1/chat/completions,温度 0.1,最多生成 80 tokens,HTTP 超时 30 秒。
  • 提示词要求只返回一行译文,并使用 /no_think;代码会移除 <think> 内容和常见“Translation:”标签。
  • 兼容 /completion 的回退在 Spark 上关闭:NOVME_OPENAI_COMPLETION_FALLBACK=0
  • 翻译成功必须持久化到 SQLite;持久化失败与模型失败同样会进入错误和结束重试路径。

会后总结细节

  • 总结输入使用最终字幕列表,每行格式为 说话人: 译文或原文
  • 当前会把整场逐字稿一次性发送给模型,没有 token 预算计算、分块总结或 map/reduce。
  • 模型必须返回 JSON:summary 为字符串,decisionsaction_itemsrisks 为字符串数组。
  • 正式 finalize 路径严格验证 JSON 类型;解析或字段类型错误会让最终处理失败。
  • citations 不是模型生成的,后端固定附上前 5 个字幕段作为引用材料。
  • Spark 总结最多生成 1024 tokens,本地 MLX 也是同一默认上限。

关键可观测字段

关键日志包含 meeting_idsourceseq、队列深度、模型 ID、 asr_msqueue_msprovider_ms、结束屏障任务数和总耗时。 这些字段用于判断瓶颈是在采集、传输、ASR、翻译排队、模型推理还是最终处理。

真实实现

当前模型与运行参数

下面区分“健康接口模型 ID”“llama-server 服务别名”和“实际模型文件”,三者不是同一概念。

模型选择不是自动切换

启动脚本通过显式的引擎配置选择本地或 Spark profile。严格模式不会因为模型不可用而偷偷换成另一个模型;当前 Spark 使用 VibeVoice,Qwen 不作为静默回退,MiMo 只作为单独的未验收 ASR POC。

Profile选择配置模型职责
Apple Silicon 本地NOVME_SPEECH_ENGINE=mlx-whisper
NOVME_TRANSLATION_ENGINE=mlx
NOVME_SUMMARY_ENGINE=mlx
Whisper Small MLX 做 ASR;共享 Qwen2.5 1.5B MLX 做翻译和总结。
DGX Spark 当前NOVME_SPEECH_ENGINE=vibevoice-asr
NOVME_TRANSLATION_ENGINE=openai-compatible
NOVME_SUMMARY_ENGINE=openai-compatible
VibeVoice-ASR 做最终 ASR;Qwen2.5 1.5B 独立负责实时翻译;DeepSeek Chat Q5 独立负责会后复核。
MiMo POCNOVME_SPEECH_ENGINE=mimo-asr只替换 Spark ASR,必须单独部署 loopback sidecar;未完成 GB10 负载、质量和回滚验收,不是默认选项。

当前 Spark 实际部署

以下值在 2026-07-31 通过远端非密钥配置、发布元数据、/health 和真实 PCM canary 严格核对, 当前认证发布为 20260731T0537Z-vibevoice-adapter-canary2;ASR、实时翻译与会后复核使用三个独立的 loopback 模型服务,说话人复盘使用独立的 CPU CampPlus 模型,彼此不会静默回退。

能力引擎 / 模型当前参数与边界
实时 ASRVibeVoice ASR
microsoft/VibeVoice-ASR
固定 revision d0c9efdb…7d944;vLLM 回环端口 18085;严格核对 served model、snapshot root、容器 image ID 与内存参数;预填原生单段 JSON 头,只让模型续写正文;请求串行;最多 512 tokens;模型不提供已验收的置信概率。
说话人标签CampPlus
iic/speech_campplus_sv_zh-cn_16k-common@v2.0.2
实时阶段仍按来源显示;会议结束后读取完整系统 WAV,在 CPU 上按音色聚类并持久化 对话人1/2/...,模型权重 SHA 和 0.31 阈值由严格健康检查锁定。
实时翻译OpenAI-compatible
qwen2.5-1.5b-realtime-local
80 tokens;前序同来源上下文 2 条;后端并发 10。真实持久字幕顺序测试 P50/P95 为 220/322 ms;英文译中文结果若没有中文会直接报错。
会后复核OpenAI-compatible
deepseek-llm-7b-chat-q5-local
独立端口和两路槽位;分层 map/reduce;1024 tokens 最终输出;135 段真实会议已完成复核与总结。

VibeVoice 接收 16 kHz PCM16 WAV。后端预填一段包含起止时间、说话人和 Content 起始引号的原生 JSON,模型只续写正文和闭合符号;后端重建完整 JSON 后严格解析,响应结构或 token 用量字段错误会直接失败,不会回退到 Qwen。日志同时记录 prompt_tokenscompletion_tokens。发布门禁先直连 provider,再用同一段 PCM 实例化并执行生产 VibeVoiceASREngine,因此会覆盖 WAV 编码、预填、JSON 重建、文本和置信度语义。 当前模型不返回已验收的置信概率,因此字幕记录中的 confidence=0.0 是明确的“不可用”哨兵, /health 同时返回 confidence_available=false,不会伪造固定高置信度。

Spark 实际 GGUF 与 llama.cpp

实时翻译文件/opt/novme/shared/models/qwen2.5-1.5b-instruct-q4_k_m.gguf
实时翻译 SHA-2566a1a2eb6d15622bf3c96857206351ba97e1af16c30d7a74ee38970e434e9407e
实时翻译服务qwen2.5-1.5b-realtime-local @ 127.0.0.1:18081
实时翻译容量40960 / 10 slots / 4096 each
会后复核文件/opt/novme/shared/models/deepseek-llm-7b-chat-q5_k_m.gguf
会后复核 SHA-2565ab7fade2ec4efe8793a1b557694a8e23a573ccccbadd2ef75d706a04a66f6c6
会后复核服务deepseek-llm-7b-chat-q5-local @ 127.0.0.1:18083
会后复核容量8192 / 2 slots / 4096 each

两个 GGUF 文件都与发布元数据中的 SHA-256 一致,部署门禁分别验证路径、哈希、别名、端口与容量。 各自的启动脚本要求总上下文能被槽数整除,并保证每槽至少 4096。历史 DeepSeek R1 Q5 评估因空译文而结束,不是活动配置,也不是失败时的自动回退。

Spark 并发实测

下表是 2026-07-13 的 Qwen 历史容量基线。当前实时 Qwen 对 20 条真实持久字幕顺序测试 P50/P95 为 220/322 ms,十路执行为 775/1056 ms;并发运行 135 段 DeepSeek 会后复核时,实时 Qwen P95 为 982 ms。

并发P50P95最大
138 ms39 ms104 ms
456 ms197 ms197 ms
1087 ms393 ms394 ms

当前 VibeVoice 使用 0.40 内存比例和显式 4G KV cache,修复了旧配置耗尽统一内存并导致 2 秒音频失败的问题。原生 JSON 段头预填又去掉了模型重复生成时间戳和说话人字段的开销:内置和外部 2 秒 provider canary 分别为 807 ms806 ms,随后同一段 PCM 通过真实生产适配器分别为 790 ms793 ms;五轮暖机后的 1/2/4 秒单请求 P50 为 621/857/1088 ms。请求仍然串行,两个同时到达的 2 秒请求分别为 864/1715 ms。17.28 秒中文样本为 4.512 s,但较短截断样本仍出现专名误识别。 这些数字只表示语音段形成后的 provider 请求耗时,不包含前端采集、至少 1 秒语音段形成、通常 800 ms 静音边界、传输和翻译,因此不能把 621 ms 宣称成所有场景的端到端字幕延迟。当前仍需完成双语、双路音频、持续混合负载、并发容量和人工质量验收。

Apple Silicon 本地 MLX

能力模型运行方式
ASRmlx-community/whisper-small-mlx16 kHz PCM;温度 0;不继承上一段文本;启动时执行 1 秒静音预热。
翻译mlx-community/Qwen2.5-1.5B-Instruct-4bit80 tokens;温度 0;带中英 few-shot 示例。
总结mlx-community/Qwen2.5-1.5B-Instruct-4bit1024 tokens;严格 JSON;与翻译共享同一个已加载运行时。

MLX 翻译和总结按精确模型 ID 共享模型、tokenizer 和一把生成锁,因此同一进程内不会并发操作该运行时。 当前自适应配置使用 80 ms 传输帧,并由后端按来源 RMS 组装语音段:常规 800 ms 静音释放、15 秒硬上限;超过 4 秒后遇到 160 ms 低能量停顿可提前释放。666.56 秒生产模型回放得到 107 段,仅 2 段触发硬上限,ASR 与翻译均无失败。

模型就绪与失败策略

  • 严格模式下,ASR、翻译、说话人和总结引擎任一不可用都会阻止后端启动;模型不会在运行中自动互换。
  • MLX 模型必须在启动阶段完成加载与真实预热;Spark VibeVoice 必须通过 served model、精确 snapshot root、revision、容器 image ID 和协议核验;任一失败都会阻止严格模式启动。
  • Spark 的 OpenAI-compatible 引擎在启动时探测回环 /health;当前就绪状态是构造时快照,不是持续容量监控。
  • /health 暴露精确引擎名称、配置模型 ID、部署修订和音频/VAD 契约;Spark 部署验证另外核对 GGUF 指纹。

开发与部署

运行模式

严格模式

默认模式。必需引擎不可用、模型身份不匹配或健康契约缺失时,后端和原生客户端都会拒绝继续。

Terminal
export NOVME_ENGINE_MODE=strict
scripts/run-backend.sh

开发模式

仅用于 UI、存储和传输开发。替代引擎会在健康状态中明确标记为降级,不会伪装成正式提供方。

Terminal
NOVME_ENGINE_MODE=development scripts/run-backend.sh

健康契约 v2

/health 必须返回部署修订、配置档、引擎模式、精确模型 ID、协商帧长、RMS 指标、来源专属阈值和完整 VAD 边界。 原生客户端和回放工具会拒绝缺失或不匹配的契约;单纯的 HTTP 200 不是可接受的部署验证。

开发与部署

DGX Spark 部署

当前发布使用受 Bearer 认证保护的直连 HTTP 配置。FastAPI 对外映射到 Spark 的 8080,推理服务仍只绑定远端回环地址。

部署顺序

Terminal
scripts/spark-deploy.sh --execute --maintenance-window
scripts/spark-verify.sh --execute

必须先完成发布验证,再打开客户端。原生客户端不会自动启动 SSH 隧道,也不会预填远端 origin;隧道脚本仍保留为运维访问路径。

Spark 直连

批准的直连 profile 是 direct-http-8080:运维者明确配置的 origin 转发到 Spark 的 FastAPI 0.0.0.0:8080。它要求 Bearer 认证,但 HTTP 不加密 Key、音频、字幕或会议数据,只适合可信网络。实时翻译 18081、会后复核 18083、可选 MiMo 18082 和 VibeVoice 18085 仍必须保持回环绑定。

Terminal
python3 -c 'import secrets; print("sk-novme-" + secrets.token_urlsafe(32))'

# 将生成的 Key 写入 Spark 的受限 secrets 文件后执行
scripts/spark-deploy.sh --execute --maintenance-window
scripts/spark-verify.sh --execute

专用 Key 写入 Spark 的 /etc/novme/novme.secrets,认证发布验证了缺失/错误 Key 的 HTTP 拒绝和 WebSocket 握手拒绝;同一 Key 由客户端用户在 macOS“设置”的“连接”页保存到 Keychain。HTTPS/WSS 是后续替代明文直连的安全目标,当前没有用它假装已经完成。

当前 Spark 配置

  • 当前发布:20260731T0537Z-vibevoice-adapter-canary2direct-http-8080、严格模式、强制 Bearer 认证并使用 UMask=0077
  • 实时 ASR:固定 revision 的 microsoft/VibeVoice-ASR,通过回环 vLLM 提供,精确核对 snapshot 和容器 image ID;后端预填单段 JSON 头、严格重建响应并串行请求。
  • 实时翻译:qwen2.5-1.5b-instruct-q4_k_m.gguf,别名 qwen2.5-1.5b-realtime-local,回环端口 18081,十路槽位。
  • 会后复核:非 reasoning 的 deepseek-llm-7b-chat-q5_k_m.gguf,别名 deepseek-llm-7b-chat-q5-local,回环端口 18083,两路槽位。
  • 实时音频:VAD 协商 80 ms 帧,按来源 RMS 阈值分类,常规 800 ms 静音释放并保留 15 秒硬上限;超过 4 秒后,160 ms 低于来源阈值 75% 的停顿会触发软边界。
  • 历史方案:固定 400 ms 静音 / 4 秒硬切已被真实回放拒绝,仅保留兼容测试;当前生产已切到自适应边界。
  • 服务:单用户、单进程、可信运维边界;FastAPI 使用 Spark 0.0.0.0:8080 直连映射,llama-server、MiMo 和 VibeVoice 保持回环。

其他

故障排查

客户端提示后端不可用

先访问当前配置对应的 /health:已安装的本地运行时是 http://127.0.0.1:18080/health,仓库开发脚本通常使用 127.0.0.1:8000,远端则使用运维者明确配置的 origin 并带上 Bearer Key。不要只验证端口是否打开,还要核对健康契约中的模型、部署身份和 VAD 参数。

麦克风或会议音频没有活动

检查 macOS 麦克风和屏幕录制权限,确认本地签名证书没有变化,并完全退出后重新打开应用。持续零系统音频会在 5 秒后显示警告。

源字幕正常,但翻译延迟

这通常表示翻译队列饱和或提供方失败。源字幕不会被丢弃;查看类型化事件与后端日志,结束会议后系统会尝试补齐翻译。

提示“音频连接积压达到上限”

这表示双路采集速度持续高于服务端归档确认速度。先检查 Spark 隧道往返延迟和后端归档日志, 再查看客户端的 audio upload protocol configuredaudio archive latency highaudio backlog stopping session 日志。不要只调大缓存阈值来延后失败。

会议结束后复盘失败

保留当前会议 ID 和逐字稿,在复盘界面对同一会议重试。检查结束屏障、待处理翻译和摘要提供方日志,不要新建会议掩盖原始失败。

其他

当前边界

以下能力仍是明确边界,不应从现有实现推断为已完成。

  • 原生 macOS 客户端尚未完成分发签名、公证和正式发布自动化。
  • Spark 的全新主机搭建、真实维护窗口回滚和断电恢复尚未完成实机验收。
  • 后端当前是可信、单用户、单进程运行边界;远端 Bearer 认证已实现,但明文 HTTP、WebSocket Origin、按用户授权、数据保留/删除、备份恢复和全局容量控制仍未完成。
  • 新的 80 ms 上传窗口已通过双路高延迟模拟,但真实 Spark 连接下至少 5 分钟的双路采集验收仍未完成。
  • 实时说话人标签不是最终精确分离结果;会后复盘负责更完整的整理。