/v1" http://JUDGE_HOST:8001 both qwen3.5-35b-a3b
```
**Output**: `eval/output/results/{model_name}/{mode}/` (mode β {tool, direct, both}).
**Path overrides via env vars**: `CSV`, `FRAMES_DIR`, `OUTPUT_DIR`, `CONFIG`, `HF_CHECKPOINT`.
**Evaluation protocol** (paper Β§5): `Direct` lets the model answer from keyframes only (tool-free); `Agentic` exposes the full tool suite (`Select_Keyframe` / `Crop_Search` / `Search` / `Visit`) with multi-turn execution. Scoring runs against an independent vLLM judge server.
### Main Results (Paper Table 1, Agentic setting)
| Model | Video-DR | VideoDR-Bench Overall | **Avg** |
|:---|:---:|:---:|:---:|
| **Video-DeepResearch-35B-A3B** (Ours) | **72.4** | **71.2** | **64.0** |
| **Video-DeepResearch-30B-A3B** (Ours) | 68.0 | 67.5 | 59.3 |
| Claude-4.5-Sonnet | 66.2 | 69.5 | 59.0 |
| Gemini 2.5 Pro | 62.0 | 53.0 | 57.5 |
| GPT-5 | β | β | 52.5 |
VideoDR-Bench spans six video domains β Knowledge, Entertainment, Daily Life, Game & Sports, News, Others β with every instance requiring joint visual grounding + multi-hop knowledge reasoning.
---
## 3. Supervised Fine-Tuning (sft/)
Built on ms-swift's `megatron sft`, with Qwen3-VL-30B-A3B-Instruct (MoE, 256 experts / top-8) as the base. Cluster: 4 nodes Γ 8 Γ 80 GiB H800 (TP=4, EP=8, CP=2, PP=1; micro=1, global=64).
**Training data** (paper Β§4.3): 7K decoupled perception-exploration trajectories + 7K VDR text-only QA. Mixed training simultaneously reinforces visual-tool use and textual deep-research capability.
Three-phase VideoHunter pipeline: (I) video filtering, (II) VQA synthesis with parametric-leakage filtering, (III) decoupled perception-exploration trajectory construction.
```bash
# Single-node quick check
bash sft/run_video_dr_sft.sh
# Multi-node (run on each node; NODE_RANK is set by your scheduler)
WORLD_SIZE=4 RANK=$NODE_RANK bash sft/run_video_dr_sft.sh
```
**Env overrides**: `MODEL_PATH`, `DATASET_PATH` (space-separated multi-path), `SAVE_PATH`, `WANDB_KEY`, `NPROC_PER_NODE`.
**Data format** (per JSONL line): `messages` (multi-turn system/user/assistant, with `` placeholders) + `images` (list of image paths aligned with placeholders).
`sft/ms-swift/` contains the ms-swift source (checkpoints / asset / docs / tests excluded). Install deps first: `pip install -r sft/ms-swift/requirements.txt`.
---
## 4. Reinforcement Learning (rl/)
GRPO training built on slime + megatron backend + SGLang rollout. Key hyperparameters (paper Β§4.3):
- **Reward**: sparse binary, `r=1` when the judge (Qwen3-VL-30B-A3B-Instruct) judges correct, else `r=0`.
- **Data**: 2K moderate-difficulty instances, Pass@4 strictly β (0, 1).
- **Negative-advantage down-sampling**: format-violating / repetitive-loop trajectories contribute their negative gradient with only 20% probability (`--negative-advantage-keep-prob 0.2`).
- **Stability knobs**: `KL=0`, `Ξ΅_clip=0.2/0.28`, `--rollout-max-response-len 64000`, `--global-batch-size 512`.
- **Model parallelism**: TP=1, PP=2, EP=8, DP=8.
**Prerequisites**:
- Ray cluster is running (`SLIME_SCRIPT_EXTERNAL_RAY=1` + `RAY_JOB_ADDR`; or set to `0` to have the script start a local head)
- **Judge server** (vLLM, OpenAI-compatible) reachable at `JUDGE_IP:JUDGE_PORT/v1/models`
- **Extract server** *(required)* β same role as in eval: `visit_tool` invokes it during rollout to summarize webpage contents. Deploy exactly as in the eval section (SGLang `/generate` or vLLM `/v1/chat/completions`) and point `rl/examples/vision_deepresearch/config.yaml`'s `extract_backend` / `extract_url` / `extract_model` at it. In practice the same judge vLLM instance can double as extract.
```bash
export SLIME_SCRIPT_EXTERNAL_RAY=1
export SLIME_SCRIPT_NUM_NODES=2
export SLIME_SCRIPT_GPUS_PER_NODE=8
export SLIME_SCRIPT_RAY_JOB_ADDR="http://127.0.0.1:8265"
export SLIME_SCRIPT_JUDGE_IP=""
export SLIME_SCRIPT_JUDGE_PORT=8001
export SLIME_SCRIPT_TRAIN_DATA="/path/to/rollout.jsonl"
bash rl/run_grpo.sh
```
`rl/slime/` is a trimmed slime framework (~1 MB β utils / rollout / backends / ray only). `rl/scripts/models/` contains per-model megatron config scripts, `rl/train.py` is the slime entry, and `rl/examples/vision_deepresearch/` holds the vdr-side env / rollout / preprocess code.
---
## Known Issues
The code reorganization here (sub-directory split, import rewrites, slime shim extraction) introduces some divergences from the original upstream. Known caveats:
- **`eval/vdr_core/rollout.py`'s `GenerateState` is a local shim** β it only exposes tokenizer/processor and is a process-wide singleton (not keyed by hf_checkpoint). Fine for single-checkpoint eval; if you need to load multiple checkpoints in the same process or plug into full slime training, restore the original implementation.
- **`eval/vdr_core/env.py`'s `_judge` uses a soft slime.rollout.rm_hub dependency** (try/except ImportError): if full slime is installed you get a real score, otherwise it returns 0.0. Eval scoring actually flows through `run_eval.py`'s `DeepResearchReward` and is unaffected; RL training requires real slime.
- **`eval/vdr_core/env.py`'s system prompt path** changed from upstream's `Path(__file__).parent/"eval"/eval_system_prompt.txt` to `Path(__file__).parent.parent/"prompts"/eval_system_prompt.txt` (aligning with the new directory layout).
- **`eval/config.yaml` explicitly sets `rollout_interaction_env_path: vdr_core.env`** so `rollout.py` finds the local env module.
- **`eval/config.yaml` paths are relative (`./output/...`)** β if you launch scripts from a different directory, either `cd eval/` or convert them back to absolute paths.
- **Env vars consumed by eval** (`ZHIPU_API_KEY` / `OSS_ACCESS_KEY_ID` / `OSS_ACCESS_KEY_SECRET` / `IMAGE_CROP_CACHE` / `EXTRACT_URL`, etc.) are automatically bridged from config.yaml to `os.environ` inside `env.build_env β _sync_tool_config_to_env` β no manual export needed, provided the run goes through config.yaml.
- **All API keys / OSS credentials in config.yaml are placeholders** (e.g. ``) β replace with valid values before running.
- **`sft/ms-swift/` contains source only, no checkpoints** β provide your own base model path. Install deps with `pip install -r sft/ms-swift/requirements.txt`.
- **`rl/slime/` is a minimal slime subset** (not full slime-2.4). If you need to hack internal slime logic, some modules may be missing β restore them from upstream.
- **`rl/run_grpo.sh`'s default `TRAIN_DATA_RAW` is a placeholder `/path/to/rollout.jsonl`** β must be overridden via `SLIME_SCRIPT_TRAIN_DATA`.
- **`preprocess/`'s `--clip-model` defaults to an empty string** β if left unset, extraction falls back to pixel-diff (faster, coarser).
For any reproduction issues, feel free to reach out: **fazii@mail.ustc.edu.cn**.
---
## Citation
```bibtex
@article{huang2026videodr,
title = {Video-DeepResearch: Towards the Next-Generation Multimodal Deepresearch Agent},
author = {Huang, Wenxuan and Zeng, Yu and Fang, Zhen and others},
journal = {arXiv preprint arXiv:2608.03979},
year = {2026}
}
```