refactor(fam-edge): 重构第一阶段 - 人物图片零额外调用 + 运行时稳定性 + 工程质量
人物图片功能重做: bbox 随核心视频分析那一次 Gemini 调用一并产出(prompts.py 加
person_appearances.bbox 字段, [ymin,xmin,ymax,xmax] 0-1000 归一化), frame_service
直接用存好的 bbox 裁剪头像/事件缩略图, 删除原来"展示时额外调用 Gemini 定位人物"的
整套逻辑(locate_person_bbox/VLM 校验/熔断), 从架构上消除与核心视频分析共抢配额的
问题; 用真实数据验证裁剪结果正确框住人物本体。
NVIDIA 模型修复: 实测原配置的 3 个模型均不可用(asset_id 引用 500/400, 不支持视频),
改用 nemotron-3-nano-omni 的 base64 内嵌视频方式(唯一实测打通), 加 max_base64_mb
防止对大文件做注定失败的编码。
Gemini 多 Key 轮换: 支持 extra_api_keys 配置多个独立项目的 key, 配额用尽时依次
换 key 重试(每换 key 需重新上传, Files API 按项目隔离)。
稳定性加固: CircuitBreaker HALF_OPEN 清空旧失败计数(修复探测一失败就重新 OPEN 的
bug); chat() 统一接入熔断器(原来只有视频分析路径检查); NVIDIA 适配器改用共享
json_parser(原来自己重复实现且不做 schema 校验); Gemini Files API 上传超时也尝试
清理远程孤儿文件; video_processor/video_queue 里直接操作 OracleDB._conn 的裸 SQL
改走新增的 set_event_start_time/mark_video_invalid/reset_video_to_pending 方法;
/health 加入队列线程存活状态; 密钥改用 ${ENV_VAR} 引用(.env 已支持自动加载),
不再明文写入 config.yaml。
工程质量: 新增 fam-edge/tests(32 个单元测试, 覆盖熔断器状态机/JSON 解析容错/
时间戳解析/bbox 坐标换算/多 key 解析), 新增 scripts/smoke_test.py(发版前接口
稳定性检查); 清理死代码(OllamaAdapter.analyze_frames、get_sync_delta 死分支、
未使用的 vision_timeout/max_concurrent_tasks 配置项); 修正 get_events_for_label
排序(改最近优先 + 过滤畸形历史时间戳)。
已部署 Oracle 并跑通 smoke test 全部 6 项检查。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 5000
|
||||
max_concurrent_tasks: 1
|
||||
|
||||
# Google 硬盘同步(rclone 负责同步落地,本段仅描述监听行为)
|
||||
gdrive_sync:
|
||||
@@ -26,9 +25,9 @@ gdrive_sync:
|
||||
oracle_db:
|
||||
path: "/opt/fam-edge/data/oracle.db"
|
||||
|
||||
# NAS 拉取同步接口鉴权 token(与 NAS oracle_sync.token 一致;明文直配,不再依赖 .env)
|
||||
# NAS 拉取同步接口鉴权 token(与 NAS oracle_sync.token 一致,走 .env,不明文入库)
|
||||
sync_api:
|
||||
token: "MLH92wv5jSDdQtHfcWJgKt-YaStn3IttjlrYxW0DwXA"
|
||||
token: "${ORACLE_SYNC_TOKEN}"
|
||||
|
||||
# 人物识别服务
|
||||
person_service:
|
||||
@@ -56,7 +55,14 @@ models:
|
||||
model_name: "gemini-flash-latest" # 主模型(每日免费配额 20 请求,按模型独立)
|
||||
fallback_models:
|
||||
- "gemini-flash-lite-latest"
|
||||
api_key: "AQ.Ab8RN6I0l8hC7hLnNHRY6qOXdch5CTWczDNlS4c1XrneGHipUQ"
|
||||
api_key: "${GEMINI_API_KEY}"
|
||||
# 多 Key 轮换(各自独立 Google Cloud 项目,配额互不影响):主 key 配额用尽时
|
||||
# 依次尝试这些 key,每个 key 都会重新走一遍模型 fallback 链。key 本身放 .env,
|
||||
# 这里只放环境变量名,不直接写密钥。
|
||||
extra_api_keys:
|
||||
- "${GEMINI_API_KEY_2}"
|
||||
- "${GEMINI_API_KEY_3}"
|
||||
- "${GEMINI_API_KEY_4}"
|
||||
timeout: 600
|
||||
# 模型级独立超时(最终值,不参与编排层 ×2 放大)
|
||||
# gemini-flash-lite 实测 ~22-34s,按用户要求放宽至 8 分钟(480s),避免大视频/排队时过早切断
|
||||
@@ -70,22 +76,27 @@ models:
|
||||
- provider: "nvidia"
|
||||
role: "vision"
|
||||
enabled: true
|
||||
# 多模型降级链(实测记录 2026-08-21):
|
||||
# omni 官方支持视频但 asset_id 引用 500;12b 400;llama-vision 不支持视频;
|
||||
# cosmos/phi/gemma/kosmos/fuyu/paligemma 均 404 端点不可用。
|
||||
# 链机制保留(asset 上传一次,逐个尝试+间隔切换),可用模型出现时自动生效。
|
||||
# 模型可用性实测记录(2026-08-21,用真实短视频逐个探测 chat.completions 接口):
|
||||
# omni(本行 model_name):video_url 只认 base64 data URI,NVCF asset_id 引用
|
||||
# 方式对它直接 500("Only base64 data URLs are supported for now")——本适配器
|
||||
# 已改为 base64 内嵌整段视频,见 max_base64_mb。确认可用(真实返回结构化 JSON)。
|
||||
# nemotron-nano-12b-v2-vl:走 asset_id 引用需要 NVCF-ASSET-DIR/
|
||||
# NVCF-FUNCTION-ASSET-IDS 请求头,这两个头的值由 NVCF 服务端按内部路径生成,
|
||||
# 客户端传什么都 400 "Invalid NVCF-ASSET-DIR",标准 OpenAI 兼容调用打不通,已移除。
|
||||
# meta/llama-3.2-11b-vision-instruct:明确不支持视频输入
|
||||
# ("At most 0 video(s) may be provided"),只能单图,已移除。
|
||||
# base64 方案受请求体大小限制(实测约 25MB 上限),真实监控视频压缩后通常在
|
||||
# 20MB 上下,超过 max_base64_mb 直接跳过(不做注定失败的慢速编码),不是本地
|
||||
# 故意限制过窄——这是当前唯一能打通的 NVIDIA 视频理解路径。
|
||||
model_name: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning"
|
||||
fallback_models:
|
||||
- "nvidia/nemotron-nano-12b-v2-vl"
|
||||
- "meta/llama-3.2-11b-vision-instruct"
|
||||
fallback_models: []
|
||||
base_url: "https://integrate.api.nvidia.com/v1"
|
||||
api_key: "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"
|
||||
api_key: "${NVIDIA_API_KEY}"
|
||||
timeout: 600
|
||||
switch_interval_sec: 5 # 模型切换间隔:一个失败后等待再试下一个
|
||||
max_base64_mb: 20 # 超过此大小直接跳过 NVIDIA,不做注定失败的编码+上传
|
||||
switch_interval_sec: 5 # 模型切换间隔:一个失败后等待再试下一个(未来加模型时用)
|
||||
model_timeouts: # 模型级独立超时(最终值,不参与 ×2)
|
||||
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning": 300
|
||||
"nvidia/nemotron-nano-12b-v2-vl": 300
|
||||
"meta/llama-3.2-11b-vision-instruct": 120
|
||||
circuit_breaker:
|
||||
enabled: true
|
||||
threshold: 5
|
||||
|
||||
Reference in New Issue
Block a user