| # 交接文档:Video Deep Research 视频优质度判别 Demo |
|
|
| > 负责人:高振坤(zhenkun / zhenkungao) |
| > 文档用途:说明本 demo 的功能、运行环境、运行方式、配置与密钥、排错与待办,便于他人接手 / 迁移到新服务器 / 后续网页化。 |
| > 代码当前位置:`/home/tione/notebook/gaozhenkun/demo/video_deep_research_demo/` |
| > 本目录已**自包含全部源码**,可整目录拷贝/建 git 后迁移。 |
| |
| --- |
| |
| ## 一、这个 Demo 做什么 |
| |
| 给定一个 **YouTube 视频链接**,自动判别该视频是否为「优质素材」(当前业务口径:是否含可抽取的**高颜值男女(帅哥/美女)素材**),输出结构化判定(`approve` / `reject` / `undecided`)+ 推理轨迹。 |
| |
| 核心方法是 **Video Deep Research**:让一个 VLM(视频多模态大模型)以「多轮工具调用」的方式自己去研究视频——抽帧、锁定关键帧、放大、反向图搜、网页文搜,最后给出判定。 |
| |
| 判别逻辑**不是**简单分类,而是:模型在每一轮自行决定调用 5 个工具中的哪一个,最终在 `<answer>` 里输出 JSON 判定,由脚本解析(`parse_answer_json`),**本链路没有独立的 LLM-as-judge 打分环节**(judge/summarizer 只在 `image_search` 摘要里用到)。 |
|
|
| ### 5 个工具(Video Deep Research 工具集) |
|
|
| | 工具 | 作用 | |
| |------|------| |
| | `choose_frames` | 选定一个时间/帧区间,返回均匀采样的若干帧 | |
| | `find_frame` | 锁定单个具体帧,细看 | |
| | `zoom_in` | 放大锁定帧的某个 bbox 区域 | |
| | `image_search` | 对锁定帧的某个区域做反向图搜(识别未知实体) | |
| | `web_search` | 文本网页搜索(已知实体,查外部知识)。本 demo 走 **Tavily** 公网搜索 | |
|
|
| > 工具定义在 `inference/attractive_leads_prompt.py` 的 `_TOOLS_BLOCK`,与训练侧 `config/tool_config/tools_video_train.yaml` 的 5 个工具一一对应(名称/参数/required 一致)。bbox 文案一处是 0–1000、一处是 0.0–1.0,运行时自动识别坐标制式,无影响。 |
| |
| --- |
| |
| ## 二、整体流程(脚本 `run_people_online_tavily.sh` 做了什么) |
|
|
| ``` |
| YouTube URL |
| │ |
| ├─[第1步 抓取] inference/fetch_youtube_online.py |
| │ yt-dlp 下载 mp4 + info.json(含评论) → 规范化 comments.json / metadata.json |
| │ 以 ---FETCH--- KEY=VALUE ---END--- 块把 VIDEO_ID/VIDEO_PATH/COMMENTS_FILE/... 回传 shell |
| │ |
| ├─[第2步 推理] inference/run_people_quality_inference.py (单条模式) |
| │ 调用 eval.py::evaluate_video_tool() 跑「5 工具多轮」推理 |
| │ ├─ 每轮请求外部 VLM 服务 (MODEL_BASE_URL, OpenAI 兼容) |
| │ ├─ web_search → Tavily (公网) |
| │ └─ image_search → 内网 gateway/Serper + summarizer (可选) |
| │ |
| └─ 产出:判定 JSON + HTML 轨迹 + 决策表 CSV + 帧图 |
| ``` |
|
|
| - **demo 本机不需要 GPU**:它是「客户端」,模型在外部 `MODEL_BASE_URL` 上已部署。 |
| - 两步之间用「临时文件 + KEY=VALUE 文本块」中转,不是函数直调(后续网页化时这里要改成 Python API)。 |
|
|
| --- |
|
|
| ## 三、运行环境 |
|
|
| ### 1. 机器 / 硬件 |
| - 无需 GPU(模型在远端服务上)。普通 CPU 机器即可。 |
| - 需能访问:① 外部 VLM 推理服务;② 公网(yt-dlp 拉 YouTube、Tavily 搜索);③(可选)内网图搜 gateway / MARS summarizer。 |
|
|
| ### 2. 系统依赖 |
| - **ffmpeg**(必需,yt-dlp 合并 mp4 用,要在 PATH)。 |
| - **yt-dlp**(pip 或系统包;脚本会在 `CONDA_ENV/bin`、`CONDA_BASE/bin`、PATH 里自动探测,也可用 `YT_DLP` 指定)。 |
| - **playwright + chromium**:`eval.py` 顶层 `import playwright`,必须装浏览器内核,否则 import 直接失败。 |
|
|
| ### 3. Python 环境 |
| 当前本地环境:conda env `/home/tione/notebook/gaozhenkun/envs/sglang`。 |
|
|
| 新机器自建: |
| ```bash |
| /home/tione/notebook/gaozhenkun/envs/sglang/bin/python -m pip install -r requirements.txt |
| PLAYWRIGHT_BROWSERS_PATH=$PWD/.playwright-browsers \ |
| /home/tione/notebook/gaozhenkun/envs/sglang/bin/playwright install chromium # 必做 |
| ``` |
| `requirements.txt` 关键依赖(版本锁自 sglang9,可放宽): |
| `aiohttp / openai / pillow / playwright / requests / beautifulsoup4 / PyYAML / numpy / yt-dlp`。 |
| `google-*`(Vertex/Gemini)仅 `--model-client vertex` 时需要,默认不用装。 |
|
|
| ### 4. 网络 / 外部依赖服务清单 |
| | 依赖 | 用途 | 走代理? | 在哪配 | |
| |------|------|---------|--------| |
| | VLM 推理服务 `MODEL_BASE_URL` | 多轮推理主模型 | 否(内网直连,加入 no_proxy) | 脚本 `MODEL_BASE_URL`,默认 `http://100.102.37.219:8008` | |
| | Tavily | `web_search` 公网搜索 | 是 | `TAVILY_API_KEY_FILE` / `TAVILY_API_KEY` | |
| | yt-dlp → YouTube | 下载视频/评论 | 是 | `HTTP_PROXY_URL` | |
| | 内网 gateway 图搜 | `image_search`(可选) | 否(no_proxy) | `GATEWAY_URL` / `GATEWAY_TOKEN` 等环境变量 | |
| | MARS summarizer | 图搜结果摘要(可选) | 否(no_proxy) | `MARS_SUMMARIZER_ADDRESS` / `MARS_SUMMARIZER_MODEL` | |
| |
| 代理机制:脚本默认 `HTTP_PROXY_URL=http://127.0.0.1:17890`,公网流量走代理,内网服务进 `no_proxy` 直连。**新机器若直连公网,设 `HTTP_PROXY_URL=""` 关掉代理。** |
|
|
| --- |
|
|
| ## 四、如何运行 |
|
|
| ### 快速开始(当前本地环境) |
| ```bash |
| cd /home/tione/notebook/gaozhenkun/demo/video_deep_research_demo |
| ./run_people_online_tavily.sh https://www.youtube.com/shorts/ZHI5IkRfXAM |
| ``` |
|
|
| ### 常用调用方式 |
| ```bash |
| # 用环境变量传 URL |
| VIDEO_URL=https://www.youtube.com/watch?v=XXXX ./run_people_online_tavily.sh |
| |
| # 限制抓取评论数 |
| MAX_COMMENTS=50 ./run_people_online_tavily.sh <url> |
| |
| # `--` 之后的参数透传给推理脚本,例如改温度 |
| ./run_people_online_tavily.sh <url> --temperature 0.6 |
| ``` |
|
|
| ### 关键环境变量(迁移时覆盖默认值) |
| | 变量 | 作用 | 默认值 | 迁移必改 | |
| |------|------|--------|:--------:| |
| | `CONDA_ENV` | 要激活的 conda 环境路径/名 | `/home/tione/notebook/gaozhenkun/envs/sglang` | 视情况 | |
| | `CONDA_BASE` | conda 安装根(`conda shell.bash hook`) | `/root/miniconda3` | 视情况 | |
| | `MODEL_BASE_URL` | VLM 服务(OpenAI 兼容 `/v1`) | `http://100.102.37.219:8008` | ✅ | |
| | `MODEL_NAME` | 模型名 | `qwen3-vl-video-dr` | 视情况 | |
| | `TAVILY_API_KEY_FILE` | Tavily key 文件(每行一个 key) | `demo/secrets/tavily_api_keys.txt` | 视情况 | |
| | `HTTP_PROXY_URL` | 公网代理;直连设 `""` | `http://127.0.0.1:17890` | ✅ | |
| | `YT_DLP` | yt-dlp 路径 | 自动探测 | 视情况 | |
| | `MAX_COMMENTS` / `MAX_TURNS` / `MAX_CONCURRENT` | 评论数 / 最大轮数 / 并发 | 100 / 10 / 1 | 可选 | |
| | `WORK_DIR` | 复用已下载产物,避免重下 | 每次新建 | 可选 | |
| | `YT_COOKIES` / `YT_COOKIES_FROM_BROWSER` | 给 yt-dlp 传 cookie(应对 YouTube 风控) | 无 | 视情况 | |
|
|
| ### 迁移示例(新机直连公网、自建 conda) |
| ```bash |
| export CONDA_ENV=/home/tione/notebook/gaozhenkun/envs/sglang |
| export CONDA_BASE=/root/miniconda3 |
| export MODEL_BASE_URL=http://<your-vlm-host>:8000 |
| export MODEL_NAME=<your-model-name> |
| export TAVILY_API_KEY=tvly-xxxxxxxx |
| export HTTP_PROXY_URL="" # 直连,不走代理 |
| ./run_people_online_tavily.sh <youtube_url> |
| ``` |
|
|
| --- |
|
|
| ## 五、产物 |
|
|
| - **抓取缓存** `<work_dir>/`(默认 `inference/online_runs/<id>_<ts>/`): |
| `<id>.mp4`、`<id>.info.json`、`comments.json`、`metadata.json`。 |
| - **推理结果** `<output_dir>/`(默认 `demo/lead_filter_runs/online_<id>_<ts>/`): |
| - `results.jsonl` — 结构化结果(含每轮工具调用) |
| - `results.html` — **可视化推理轨迹**(逐轮工具/帧图,演示首选) |
| - `summary.json`、`decision_table.csv` — 判定汇总 |
| - `images/`、`frame_cache/` — 抽帧与裁剪图 |
| - **日志** `<output_dir>.log`。 |
|
|
| --- |
|
|
| ## 六、配置与密钥 ⚠️(迁移 / 建 git 必读) |
|
|
| `video_dr_gen/config.py` 已改为**从环境变量读取凭证和内网地址**,默认不再写死旧机器路径或明文 secret: |
|
|
| | 位置 | 内容 | |
| |------|------| |
| | `config.py` | `SERPER_API_KEY`、`GATEWAY_URL/USERNAME/USERID/GATEWAY_TOKEN`、`MARS_RETRIEVAL_ADDRESS`、`MARS_SUMMARIZER_ADDRESS`、OSS 配置均读环境变量 | |
| | `run_people_online_tavily.sh` | `TAVILY_API_KEY_FILE` 默认指向 `demo/secrets/tavily_api_keys.txt`;`MODEL_BASE_URL` 仍需按实际模型服务配置 | |
|
|
| **因此:** |
|
|
| 1. 不要把真实 `GATEWAY_TOKEN`、`SERPER_API_KEY`、Tavily key、OSS key 写回源码或提交。 |
| 2. `MARS_SUMMARIZER_ADDRESS` 默认空,自检会跳过;只有显式配置后才会探测。 |
| 3. 若需要 `image_search`,需要额外配置 gateway/Serper 与 OSS 上传相关环境变量,否则该工具会返回配置缺失错误。 |
|
|
| --- |
|
|
| ## 七、运行前自检 |
| ```bash |
| # 1) 模型服务可达? |
| curl "$MODEL_BASE_URL/v1/models" |
| |
| # 2) 源码闭包可导入?应输出 IMPORT_OK |
| cd demo/inference && python -c "import fetch_youtube_online, run_people_quality_inference; print('IMPORT_OK')" |
| |
| # 3) ffmpeg / yt-dlp / chromium 就绪? |
| ffmpeg -version | head -1; yt-dlp --version; python -c "from playwright.sync_api import sync_playwright; print('pw ok')" |
| ``` |
|
|
| --- |
|
|
| ## 八、常见问题排错 |
|
|
| | 现象 | 原因 / 处理 | |
| |------|------| |
| | import 阶段报 playwright 相关错 | 没装内核:`playwright install chromium` | |
| | yt-dlp 下载失败 / 被风控 / 403 | YouTube 对云 IP 风控。配 `HTTP_PROXY_URL`,或用 `YT_COOKIES` / `YT_COOKIES_FROM_BROWSER` 传 cookie;必要时降频 | |
| | 启动卡在自检 / judge 连不上 | `config.py` 的 `MARS_SUMMARIZER_ADDRESS` 内网不可达,按第六节设为 `""` | |
| | `web_search` 报缺 key | 提供 `TAVILY_API_KEY` / `TAVILY_API_KEYS` / `TAVILY_API_KEY_FILE` 三选一 | |
| | 模型请求超时 | 检查 `MODEL_BASE_URL` 可达、模型名 `MODEL_NAME` 是否匹配;`curl $MODEL_BASE_URL/v1/models` | |
| | 内网服务走了代理连不上 | 确认该地址在脚本 `no_proxy` 列表里(默认已含模型 host 与 MARS 地址) | |
| | ffmpeg 报错 / mp4 合并失败 | 装 ffmpeg 并加入 PATH | |
|
|
| --- |
|
|
| ## 九、目录结构速查 |
| ``` |
| demo/ |
| ├── run_people_online_tavily.sh # 入口脚本(REPO_ROOT 自动取本目录) |
| ├── requirements.txt # Python 依赖(锁自 sglang9) |
| ├── README.md # 简版说明 |
| ├── HANDOVER.md # 本交接文档 |
| ├── inference/ |
| │ ├── fetch_youtube_online.py # 第1步:yt-dlp 抓视频/评论 |
| │ ├── run_people_quality_inference.py# 第2步:单条筛选推理入口(含 health_check) |
| │ ├── attractive_leads_prompt.py # ★工具定义 _TOOLS_BLOCK + 业务 system prompt |
| │ ├── eval.py # 核心引擎:5工具多轮 + Tavily/图搜 + HTML 轨迹 |
| │ └── video_dr_bridge.py # 桥接层:自动定位 video_dr_gen(VIDEO_DR_SOURCE_ROOT 可覆盖) |
| └── video_dr_gen/ # 被 bridge 依赖的闭包(4 文件) |
| ├── config.py # 本地默认配置,secret/内网地址从环境变量读取 |
| ├── utils.py # normalize_bbox / crop_frame / real_image_search ... |
| ├── prompts.py |
| └── assemble_sft_dataset.py |
| ``` |
| > `inference/` 与 `video_dr_gen/` 必须保持现在的相对位置(同在 `demo/` 下)。 |
|
|
| --- |
|
|
| ## 十、已知问题 / 后续待办 |
|
|
| 1. **网页化(GitHub / HuggingFace Space)需新增**: |
| - Web 层(Gradio/FastAPI)包住现有两步 CLI; |
| - 把 shell+文件中转改成可调用、可流式吐进度的 Python API(推理耗时长,需进度条); |
| - 系统依赖打包(ffmpeg / playwright chromium,Dockerfile 或 HF `packages.txt`); |
| - 增加「本地视频上传」备选输入,规避云端拉 YouTube 被风控; |
| - 并发队列 / 超时 / 临时目录清理 / 限流。 |
|
|
| --- |
|
|