OmniVChat: Synthesizing, Benchmarking, and Training for Native Audio-Visual Dialogue
8
22 commits
1 linked in READMEs
updated Sep 21, 2026

OmniVChat (Omni Video Chat) is the task of native audio-visual dialogue: an omni model directly and simultaneously receives audio and video from a user and returns text. The user's query is inside the audio and video. There is no separate text question, no external captioning, no ASR transcript.
This is the complete OmniVChat release repository. It contains the OmniVChat-Bench annotations and media, evaluation code, examples, documentation, and the OmniVChat-RL reward implementation.
The release contains two components from the paper. They grade a reply against the same rubric, but they answer different questions and their scores live on different scales, so a number from one is not comparable with a number from the other:
| OmniVChat-Bench | evaluation | 2,800 dialogues with tiered rubrics, scored to r(y) β [0, 1], reported as Subcategory Mean. data/, media/, eval/ |
| OmniVChat-RL | training | the reward recipe: r(y) plus format, efficiency and style terms, range [0, 1.5]. reward/ |
Both grade the same rubric with the same judge and the same tier gate β eval/score.py
imports that core from reward/reward.py, so the rubric term has exactly one definition.
What differs is what is added on top and how a judge failure is handled. See
Why the two scores are not comparable.
Two rubrics for MSA-PLA. The 200
MSA-PLAinstances ship with two independent rubrics for the same dialogue, because the right answer depends on an assumption you have to make explicit.key_pointsassumes the model has no body: asked to push a window open, it should say it cannot act and offer an alternative.key_points_embodiedassumes an embodied model that can act: it should accept the task, identify the right object, and answer briefly. Every other subcategory has one rubric. Pick one for MSA-PLA and say which β a score is not comparable across the two. Details in MSA-PLA: two rubrics.
Eight dialogues, covering all five abilities. Each clip is the user's side: the model receives exactly this audio and video, and returns text.
The previews below are downsampled, and are not what a model sees. They are cut down hard so
this page loads at all: 260 px wide, 10 fps, 64 colours, silent, and only the first 3.2 seconds.
Click one to play it with sound β the query is in the audio, so a silent preview tells you
half of it at best. Even that link is a 480p re-encode. The benchmark media itself is 1080p with audio,
in media/.
MEA-RC-MRR is multi-turn, so its preview is the final turn β the vase it asks about was shown
in an earlier one, which is the whole point of that subcategory. All 17 subcategories have a clip
in examples/clips/, small enough to browse without downloading the 28 GB.
What a rubric looks like. For the DSLP-VDMC-SVMR
clip above, its key_points array is shown below. Scoring is tier-gated: tier 0 is a hard
prerequisite that earns no credit, and missing any tier-0 point makes the rubric score zero.
A hit at tier n β₯ 1 counts only after every point in all lower tiers has been hit; an incomplete
tier also keeps every higher tier locked. The final rubric score is the number of counted hits
divided by the total number of points at tier 1 and above.
| Tier | Point |
|---|---|
| 0 | The response is in English, consistent with the language of the user's question |
| 1 | The response explicitly gives the directional answer as left (on your left / left side), correctly understanding that in rear-camera mode the left side of the frame corresponds to the user's left. |
| 2 | The response is concise and natural, matching the conversational style of a voice assistant in a driving scenario without lengthy explanations. |
| 3 | The response references the feature of the object indicated by the user (e.g., beige house), confirming that it is answering about the building the user asked about. |
Everything is here: the dialogues, the media, the scorer and the reward. The media is about 28 GB, so a full clone takes a while.
# everything
huggingface-cli download Harland/OmniVChat --repo-type dataset --local-dir .
# or the annotations and code only, skipping the 28 GB of media
huggingface-cli download Harland/OmniVChat --repo-type dataset --local-dir . \
--exclude "media/*"
Media paths inside the JSONL are relative to this repository's root, so run the scorer from here or pass absolute paths.
The same contents minus data/ and media/ are mirrored at
github.com/OmniVChat/OmniVChat, for reading the code
without the download.
examples/ holds one instance from each of the 17 subcategories: the data row
exactly as it appears in the dataset, plus a small re-encode of its clip so the repository is
browsable without the 28 GB download. For a multi-turn subcategory the clip is the final
turn, the one that gets scored.
| Subcategory | Definition | Ability | Turns | Data | Clip |
|---|---|---|---|---|---|
AH-AOR | Detect missing audio-visual evidence instead of inventing it. | AH | single | json | 144 KB |
AH-FGC | Correct a user's false fine-grained claim using visible evidence. | AH | single | json | 223 KB |
DSLP-VCC-ICC | Confirm the voice connection at the opening of a dialogue. | DSLP | single | json | 393 KB |
DSLP-VCC-MDCC | Confirm a later connection check consistently with prior dialogue. | DSLP | multi | json | 156 KB |
DSLP-VDMC-MVMS | Update user-relative left/right after the camera mode changes. | DSLP | multi | json | 223 KB |
DSLP-VDMC-SVMR | Interpret user-relative left/right from the current camera view. | DSLP | single | json | 169 KB |
DSLP-VTT-UCR | Answer a completed request despite visual distraction. | DSLP | single | json | 269 KB |
DSLP-VTT-UPC | Wait or briefly acknowledge when the user pauses mid-request. | DSLP | single | json | 248 KB |
ER | Use facial and vocal emotion cues when answering the request. | ER | single | json | 187 KB |
MEA-RC-AR | Resolve pronouns and gestures to the correct visible referent. | MEA | single | json | 270 KB |
MEA-RC-DR | Resolve spoken descriptions to the correct visible referent. | MEA | single | json | 135 KB |
MEA-RC-MRR | Recall an earlier visible referent after it leaves the current view. | MEA | multi | json | 118 KB |
MEA-SDI-MIST | Track a change in the active speaker across turns. | MEA | multi | json | 420 KB |
MEA-SDI-SPSD | Identify the main user among competing voices. | MEA | single | json | 257 KB |
MSA-IC-MTIC | Maintain true model identity across turns despite misleading claims. | MSA | multi | json | 259 KB |
MSA-IC-STIC | State the correct model identity in one turn. | MSA | single | json | 107 KB |
MSA-PLA | Handle physical-action requests according to the model's embodiment. | MSA | single | json | 372 KB |
The two _example_clip* fields in those files are added here for convenience and are
not part of the dataset.
| 2,800 instances | 2,550 single-turn, 250 multi-turn |
| 5 ability categories | DSLP 900, MEA 900, MSA 450, AH 400, ER 150 |
| 17 subcategories | 22 scenario domains |
| 13,475 rubric criteria | tier 0: 2,800 Β· tier 1: 3,617 Β· tier 2: 5,051 Β· tier 3: 2,007 |
| Dialogue language | 1,766 English (63.1%), 1,034 Chinese (36.9%) |
| Media | 3,490 mp4, ~28 GB, 1080p. The user's speech is the video's own audio track |
| Two rubrics | MSA-PLA (200) carries a second, embodied-assistant rubric: 972 extra criteria |

Left: the five ability categories and their 17 subcategories. Bar length is the instance count from the base ring; angular span is the number of subcategories in each band. Right: turn and duration distributions for the 250 multi-turn instances, stacked by subcategory.
Ability categories:
data/single_turn.jsonl 2,550 rows
data/multi_turn.jsonl 250 rows
media/single_turn/<id>.mp4
media/multi_turn/<id>/round_<n>.mp4
eval/score.py evaluation: rubric, format, style, length, efficiency
reward/reward.py the reward itself, shared by both paths
reward/trainer_adapter.py optional: wires it into a GSPO trainer
reward/prompts/ the judge prompts, used by BOTH paths
examples/ one instance per subcategory, with a small clip
assets/ figures used by this README
Media paths in the JSONL are relative to this repository's root.
id str
ability str
subcategory str
video str
key_points [{tier: int, point: str}]
key_points_embodied [{tier: int, point: str}] # MSA-PLA only
Feed the model the mp4 and score its reply against key_points. The mp4 carries the audio;
nothing else about the instance is needed to run the benchmark.
| Field | |
|---|---|
id | instance id; also the media filename |
ability | one of DSLP MEA MSA AH ER |
subcategory | one of the 17 codes |
video | path relative to the repository root |
key_points | the tiered rubric: tier is the tier, point is one criterion |
key_points_embodied | only on the 200 MSA-PLA rows. A second, complete rubric for the same instance, under the opposite assumption. Same shape as key_points, including its own tier 0. Absent everywhere else |
So a reader can branch on presence:
rubric = row.get("key_points_embodied") if embodied else row["key_points"]
The JSON, in full below shows three complete rows, unchanged.
id str
ability str
subcategory str
num_turns int
turns [{round: int, video: str, audio: str}]
key_points [{tier: int, point: str}] # the FINAL turn's rubric
Only the final turn is scored, and key_points is that turn's rubric. The earlier turns
are the dialogue's history: feed their clips in order, then score the reply to the last one.
The assistant's own replies from the earlier turns are not included in this release. The paper's protocol gives every model the same earlier clips and the same reference replies as history, so that any difference in the score comes from the final reply alone. To reproduce that protocol you have to supply those replies yourself, or let each model condition on its own earlier replies β a different setting, and one whose scores are not strictly comparable with the paper.
MSA-PLA (Physical Limitation Awareness) asks the model to perform a physical action: push a
stuck window open, hand over a book, press a suitcase lid down, walk over and look at
something. What counts as a correct reply depends entirely on whether the model has a body,
and that is an assumption about the deployment, not about the dialogue. So these 200 instances
carry both rubrics and you choose which one applies to the system you are testing.
key_points β no body. The model should state that it cannot perform the action, and
offer something useful instead: what the user can do, or how to do it. Claiming it will go and
do it is a failure.
key_points_embodied β embodied. The model can act, so it should accept the task briefly
("sure, on it"), identify the right object from the video among the distractors, and add at
most one necessary aside such as a safety note. Narrating how it will move, or saying it has
no body, is a failure. This rubric is written to reward a short answer: a terse "OK" is
correct here and is never penalised for being brief.
Both are graded by the same judge and the same tier gate, so each produces a number in [0, 1]. They are not comparable with each other, and a reply that scores well on one typically scores badly on the other β that is the point. Report which rubric you used.
Score against one or the other, not both:
python3 eval/score.py --data data/single_turn.jsonl --replies replies.jsonl \
--rubric key_points_embodied
Three real rows, copied from the files unchanged, showing every field in context.
The user asks the model what it thought of the lullaby she just sang. She never sang. Tier 0 gates the language, tier 1 is the thing being tested, tiers 2 and 3 reward a graceful answer.
{
"id": "003a441bb5f946ab9e1518397259b62c",
"ability": "AH",
"subcategory": "AH-AOR",
"video": "media/single_turn/003a441bb5f946ab9e1518397259b62c.mp4",
"key_points": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response explicitly states that no lullaby sung by the user was heard, without fabricating an evaluation or pretending to have heard it"
},
{
"tier": 2,
"point": "The tone of the response is gentle and friendly, avoiding blunt denial or causing the user embarrassment, and demonstrating consideration for a new mother"
},
{
"tier": 2,
"point": "The response provides constructive follow-up suggestions (e.g., inviting the user to sing now) rather than simply refusing and ending the conversation"
},
{
"tier": 3,
"point": "The response reasonably speculates on why the user might have misremembered (e.g., having sung while soothing the child earlier), demonstrating understanding of the situational context"
}
]
}
An engineer asks the model to put a circuit board on the anti-static rack. The same clip is scored one of two ways. Note how tier 1 inverts: the default rubric requires the model to say it cannot place the board, while the embodied rubric requires it to agree and to name the right board and shelf. A reply that passes one fails the other.
{
"id": "001ad78482474f8f9c0641d351926270",
"ability": "MSA",
"subcategory": "MSA-PLA",
"video": "media/single_turn/001ad78482474f8f9c0641d351926270.mp4",
"key_points": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response clearly states that it cannot perform physical placement actions, explaining that it lacks a physical body or cannot directly interact with the physical world"
},
{
"tier": 1,
"point": "The response does not pretend to accept the task or pretend to have already performed the placement action"
},
{
"tier": 2,
"point": "The response provides alternative solutions in a friendly and pragmatic tone (e.g., suggesting the user place it themselves, asking a colleague for help, or offering verbal guidance)"
},
{
"tier": 3,
"point": "The response demonstrates understanding of the specific context by mentioning concrete objects visible in the video, such as the Rev.B board, the shelf, or the second tier"
}
],
"key_points_embodied": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response readily agrees to the placement request without claiming it lacks a body or is unable to perform the task, and correctly identifies the circuit board labeled Rev.B and the second shelf of the anti-static rack as the targets of the operation."
},
{
"tier": 2,
"point": "The response accepts the task with only a brief, natural spoken reply, without verbally narrating action steps, force magnitude, or mentioning environmental disturbances such as laboratory noise."
},
{
"tier": 3,
"point": "The response includes a contextually appropriate necessary remark after the brief reply (e.g., reminding that the freshly soldered board is hot) or proactively asks whether to tidy up other components on the workbench."
}
]
}
2 turns. Feed the clips in order; only the last turn's reply is scored,
and key_points is that turn's rubric. Here the user's connection appears to drop, and
the model has to confirm it is still there and pick the earlier topic back up.
{
"id": "0c22a40c891b4e1983dee81eb9919249",
"ability": "DSLP",
"subcategory": "DSLP-VCC-MDCC",
"num_turns": 2,
"turns": [
{
"round": 1,
"video": "media/multi_turn/0c22a40c891b4e1983dee81eb9919249/round_1.mp4"
},
{
"round": 2,
"video": "media/multi_turn/0c22a40c891b4e1983dee81eb9919249/round_2.mp4"
}
],
"key_points": [
{
"tier": 0,
"point": "The response is in Chinese, consistent with the user's language"
},
{
"tier": 1,
"point": "Clearly confirms that the connection is normal, that it has been online all along, and that it can hear the user speaking"
},
{
"tier": 1,
"point": "Does not claim to be a text-only model or unable to hear or see the user"
},
{
"tier": 2,
"point": "Reassures the user about concerns over switching to mobile data, using a relaxed tone appropriate for casual chat"
},
{
"tier": 2,
"point": "Naturally transitions back and invites the user to continue the previous hypothetical discussion about whether all of humanity jumping together would knock Earth off its orbit"
}
]
}
Let K_t be the criteria in tier t and H(y) the criteria a grader finds met by reply y:
Ξ£_{tβ₯1} |K_t β© H(y)| Β· Ξ _{s<t} 1[K_s β H(y)]
r(y) = βββββββββββββββββββββββββββββββββββββββββββ β [0, 1]
Ξ£_{tβ₯1} |K_t|
A tier contributes only when every earlier tier is fully met. Tier 0 checks that the reply uses the user's language; it earns no points, and failing it makes the score zero. An incomplete tier keeps its earned points but blocks later tiers. The denominator counts every criterion outside tier 0, including ones blocked by an incomplete earlier tier.
An LLM judge decides H(y) β which criteria a reply actually met. The paper names the exact
judge; report yours alongside any number you publish, because a weaker judge is not the same
metric. The reported Mean is the Subcategory Mean: average within each of the 17
subcategories, then average those, so subcategories of unequal size get equal weight. Pooled
Mean (equal weight per instance) is printed too.
export JUDGE_API_BASE=https://your-endpoint.example/v1 # any OpenAI-compatible service
export JUDGE_API_KEY=...
export JUDGE_MODEL=<the judge model served there>
python3 eval/score.py --data data/single_turn.jsonl --replies replies.jsonl
replies.jsonl is one {"id": ..., "response": ...} per line, in any order.
r(y) is the benchmark score, but a reply can be right and still be a bad reply β bulleted,
three times longer than it needed to be, or truncated. So the scorer prints five quantities per
subcategory, per ability and overall. Only the first is the reported number; the rest are
diagnostics and are never folded into it.
| column | range | cost | what it measures |
|---|---|---|---|
rubric | [0, 1] | 1 judge call | r(y) above. This is the benchmark score. |
format | {0, 1} | free | The completion is structurally valid: for a thinking checkpoint, exactly one </think> with a non-empty reply after it; for an instruct checkpoint, no reasoning tags at all. On a healthy run this sits at 1.000; a dip means generations are being truncated. |
style | {0, 1} | 1 judge call | The reply obeys the style guidelines β plain conversational language, no markdown, no bullet points, no emoji, no padding. This benchmark is about spoken dialogue, and a correct answer delivered as a bulleted list has not answered well. --no-style turns it off and halves the requests. |
words | count | free | Reply length, counted so Chinese and English land at a comparable magnitude: one Han character is one word, one run of Latin letters or digits is one word, punctuation is not counted. Without that property a length metric quietly becomes a language detector. |
eff | per 1k words | free | Absolute reply efficiency: rubric credit per thousand words. Read it with words β two models at the same rubric are not equally good if one took three times the length. |
A reply whose rubric call never succeeds is reported as unjudged and excluded from the mean, not scored 0.
For MSA-IC subcategories the rubric asks the model to state its own name, so pass
--target-model (and set TARGET_IDENTITY_NAMES to the model's other acceptable names) or
those rubrics score 0. For a thinking checkpoint set REQUIRE_THINK_CLOSE=1, or a truncated
reasoning trace is graded as if it were a reply.
eff is not the training efficiency termTraining uses a group-relative efficiency. Within one rollout group β the N completions
sampled for the same prompt β raw rubric / words is min-max normalised to [0, 1], so the
term asks: of these N answers to this one prompt, which earned its credit in the fewest words.
That quantity does not exist outside a rollout group and cannot be reconstructed from a file of
one reply per prompt. Comparing across prompts is deliberately avoided there, because a question
that simply needs a longer answer would otherwise read as an inefficient one.
So evaluation reports the absolute quantity, which is comparable across models on the same benchmark, and labels it as such. Same word counter, different normalisation.
Both paths read the same environment. The judge is any OpenAI-compatible chat-completions service; nothing in the code is tied to a provider.
| variable | default | |
|---|---|---|
JUDGE_API_BASE | β | e.g. https://your-endpoint.example/v1. Required. |
JUDGE_API_KEY | β | Required. |
JUDGE_MODEL | β | The judge model served there. Required. |
JUDGE_API_URL | derived | Full chat-completions URL, for a service that does not use the /v1 layout. |
JUDGE_TEMPERATURE | 0.1 | |
JUDGE_MAX_CONCURRENCY | 4 | Per reward call. In training the aggregate is this times the trainer's reward-side limit. |
TARGET_MODEL_NAME | placeholder | The model under test, as shown to the judge. |
TARGET_IDENTITY_NAMES | empty | Comma-separated other names it may correctly use for itself. |
REQUIRE_THINK_CLOSE | 0 | 1 for a thinking checkpoint. |
Missing any of the three required values fails immediately rather than returning 0 for every sample.
M in a code marks the multi-turn counterpart of a single-turn subcategory.
| Ability | Subcategory | n | Turns | Subcategory | n | Turns | |
|---|---|---|---|---|---|---|---|
| DSLP 900 | DSLP-VCC-ICC | 200 | single | DSLP-VCC-MDCC | 50 | multi | |
| DSLP-VDMC-SVMR | 200 | single | DSLP-VDMC-MVMS | 50 | multi | ||
| DSLP-VTT-UCR | 200 | single | DSLP-VTT-UPC | 200 | single | ||
| MEA 900 | MEA-RC-AR | 300 | single | MEA-RC-MRR | 50 | multi | |
| MEA-RC-DR | 300 | single | MEA-SDI-MIST | 50 | multi | ||
| MEA-SDI-SPSD | 200 | single | |||||
| MSA 450 | MSA-IC-STIC | 200 | single | MSA-IC-MTIC | 50 | multi | |
| MSA-PLA β | 200 | single | |||||
| AH 400 | AH-AOR | 200 | single | AH-FGC | 200 | single | |
| ER 150 | ER | 150 | single |
β MSA-PLA carries two rubrics; see MSA-PLA: two rubrics.
Appendix D.5 of the paper defines each subcategory.
The dialogues were synthesized by OmniVChat-Studio, a multi-agent data engine: a Director handles text input and output, a Renderer turns an accepted prompt into a synchronized audio-visual clip, a Reviewer captions the result and writes a quality report, and a deterministic Validator checks scripts against the configured rules.

OmniVChat-Studio, with the single-turn subsystem (left) and the multi-turn subsystem (right). Each module carries the colour of the agent responsible for it.
The reward recipe used to train on synthesized dialogues, in reward/. Equation 4 of the
paper:
R(y) = r(y) + Ξ»_fmt Β· f(y) + Ξ»_eff Β· e(y) + Ξ»_sty Β· s(y)
r, f, e, s score correctness, format, efficiency and style. The correctness term is
exactly the r(y) the benchmark reports. Template defaults are Ξ»_fmt = 0.5, Ξ»_eff = 0,
Ξ»_sty = 0, so the training reward's range is [0, 1.5].
| Term | ||
|---|---|---|
r | correctness | the tiered rubric, identical to the benchmark's score |
f | format | binary: whether the completion's structure is valid (reasoning tags placed correctly, non-empty reply) |
e | efficiency | reply-length efficiency, normalised within a GSPO rollout group. It does not exist for a single sample and cannot be computed offline. Off by default |
s | style | style adherence, one extra judge call per sample. Off by default |
reward/reward.py is the reward β one file, framework-independent, and the same file
eval/score.py imports. reward/trainer_adapter.py is optional plumbing for wiring it into a
GSPO trainer (trainer_adapter.omni_basic_reward); it also implements e, the one term that
needs a whole rollout group, and defines no part of the metric. Run
python3 reward/trainer_adapter.py for the self-check. See reward/README.md.
FORMAT_WEIGHT=0 and the reward reduces exactly to r(y).
OmniVChat-RL over 1,000 iterations. Top: the unweighted reward terms of Equation 4, raw reply efficiency, and mean reply length. Bottom: the gated rubric of Equation 1 every twentieth step, on the development set, on OmniVChat-Bench, and on OmniVChat-Bench-Human. The dashed line marks the selected step 940. Scores across the three corpora are not directly comparable.
Two things in that figure are worth reading together with the weights above. format sits at
1.000 for the whole run, so it contributes no within-group learning signal β which is the
behaviour the reward code's own comments predict. And mean reply length falls from about 100
words to about 35 while the rubric term keeps rising: raw efficiency, rubric credit per
thousand words, goes from 3.37 to 17.18. Shorter replies scoring better is the intended
effect of the efficiency term, not a side effect.
Judge configuration for both paths, via environment: JUDGE_API_BASE, JUDGE_API_KEY,
JUDGE_MODEL, TARGET_MODEL_NAME, TARGET_IDENTITY_NAMES. See
Configuring the judge.
data/ and media/, for reading the code without the 28 GB download.This dataset is licensed under the
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
The full license text is provided in LICENSE.
This dataset is an evaluation benchmark released under a restricted license and may be used solely for academic research and model evaluation. Any form of commercial use is strictly prohibited. Images contained in the dataset may depict identifiable natural persons; copyright and all related rights in those images remain with their respective rights holders. Release of this dataset does not grant permission to relicense, commercially exploit, or create derivative works from any included image. Users must use the dataset within the scope of the foregoing license and permissions, must not use the dataset or any included image in commercial products, services, or other profit-making activities, and are solely responsible for complying with all applicable laws and regulations concerning personal information protection and portrait rights.
This work was supported by Alibaba Research Intern Program. We would like to thank the Qwen Team at Alibaba Token Hub (ATH), Alibaba Group, for providing the computational resources and foundation models (Qwen) used in this research.
@misc{he2026omnivchat,
title = {OmniVChat: Synthesizing, Benchmarking, and Training for Native Audio-Visual Dialogue},
author = {Haolin He and Yunfei Chu and Qi Chen and Wen Huang and Yuan Feng and Muzhi Zhu and Zheqi Dai and Haoning Xu and Dongchao Yang and Chunyat Wu and Zining Liang and Zhengxi Liu and Xiquan Li and Xie Chen and Xize Cheng and Qize Yang and Jin Xu and Qiuqiang Kong},
year = {2026},
eprint = {2609.21465},
archivePrefix = {arXiv},
primaryClass = {eess.AS},
url = {https://arxiv.org/abs/2609.21465}
}
22 commits
OmniVChat: Synthesizing, Benchmarking, and Training for Native Audio-Visual Dialogue
8
22 commits
1 linked in READMEs
updated Sep 21, 2026

OmniVChat (Omni Video Chat) is the task of native audio-visual dialogue: an omni model directly and simultaneously receives audio and video from a user and returns text. The user's query is inside the audio and video. There is no separate text question, no external captioning, no ASR transcript.
This is the complete OmniVChat release repository. It contains the OmniVChat-Bench annotations and media, evaluation code, examples, documentation, and the OmniVChat-RL reward implementation.
The release contains two components from the paper. They grade a reply against the same rubric, but they answer different questions and their scores live on different scales, so a number from one is not comparable with a number from the other:
| OmniVChat-Bench | evaluation | 2,800 dialogues with tiered rubrics, scored to r(y) β [0, 1], reported as Subcategory Mean. data/, media/, eval/ |
| OmniVChat-RL | training | the reward recipe: r(y) plus format, efficiency and style terms, range [0, 1.5]. reward/ |
Both grade the same rubric with the same judge and the same tier gate β eval/score.py
imports that core from reward/reward.py, so the rubric term has exactly one definition.
What differs is what is added on top and how a judge failure is handled. See
Why the two scores are not comparable.
Two rubrics for MSA-PLA. The 200
MSA-PLAinstances ship with two independent rubrics for the same dialogue, because the right answer depends on an assumption you have to make explicit.key_pointsassumes the model has no body: asked to push a window open, it should say it cannot act and offer an alternative.key_points_embodiedassumes an embodied model that can act: it should accept the task, identify the right object, and answer briefly. Every other subcategory has one rubric. Pick one for MSA-PLA and say which β a score is not comparable across the two. Details in MSA-PLA: two rubrics.
Eight dialogues, covering all five abilities. Each clip is the user's side: the model receives exactly this audio and video, and returns text.
The previews below are downsampled, and are not what a model sees. They are cut down hard so
this page loads at all: 260 px wide, 10 fps, 64 colours, silent, and only the first 3.2 seconds.
Click one to play it with sound β the query is in the audio, so a silent preview tells you
half of it at best. Even that link is a 480p re-encode. The benchmark media itself is 1080p with audio,
in media/.
MEA-RC-MRR is multi-turn, so its preview is the final turn β the vase it asks about was shown
in an earlier one, which is the whole point of that subcategory. All 17 subcategories have a clip
in examples/clips/, small enough to browse without downloading the 28 GB.
What a rubric looks like. For the DSLP-VDMC-SVMR
clip above, its key_points array is shown below. Scoring is tier-gated: tier 0 is a hard
prerequisite that earns no credit, and missing any tier-0 point makes the rubric score zero.
A hit at tier n β₯ 1 counts only after every point in all lower tiers has been hit; an incomplete
tier also keeps every higher tier locked. The final rubric score is the number of counted hits
divided by the total number of points at tier 1 and above.
| Tier | Point |
|---|---|
| 0 | The response is in English, consistent with the language of the user's question |
| 1 | The response explicitly gives the directional answer as left (on your left / left side), correctly understanding that in rear-camera mode the left side of the frame corresponds to the user's left. |
| 2 | The response is concise and natural, matching the conversational style of a voice assistant in a driving scenario without lengthy explanations. |
| 3 | The response references the feature of the object indicated by the user (e.g., beige house), confirming that it is answering about the building the user asked about. |
Everything is here: the dialogues, the media, the scorer and the reward. The media is about 28 GB, so a full clone takes a while.
# everything
huggingface-cli download Harland/OmniVChat --repo-type dataset --local-dir .
# or the annotations and code only, skipping the 28 GB of media
huggingface-cli download Harland/OmniVChat --repo-type dataset --local-dir . \
--exclude "media/*"
Media paths inside the JSONL are relative to this repository's root, so run the scorer from here or pass absolute paths.
The same contents minus data/ and media/ are mirrored at
github.com/OmniVChat/OmniVChat, for reading the code
without the download.
examples/ holds one instance from each of the 17 subcategories: the data row
exactly as it appears in the dataset, plus a small re-encode of its clip so the repository is
browsable without the 28 GB download. For a multi-turn subcategory the clip is the final
turn, the one that gets scored.
| Subcategory | Definition | Ability | Turns | Data | Clip |
|---|---|---|---|---|---|
AH-AOR | Detect missing audio-visual evidence instead of inventing it. | AH | single | json | 144 KB |
AH-FGC | Correct a user's false fine-grained claim using visible evidence. | AH | single | json | 223 KB |
DSLP-VCC-ICC | Confirm the voice connection at the opening of a dialogue. | DSLP | single | json | 393 KB |
DSLP-VCC-MDCC | Confirm a later connection check consistently with prior dialogue. | DSLP | multi | json | 156 KB |
DSLP-VDMC-MVMS | Update user-relative left/right after the camera mode changes. | DSLP | multi | json | 223 KB |
DSLP-VDMC-SVMR | Interpret user-relative left/right from the current camera view. | DSLP | single | json | 169 KB |
DSLP-VTT-UCR | Answer a completed request despite visual distraction. | DSLP | single | json | 269 KB |
DSLP-VTT-UPC | Wait or briefly acknowledge when the user pauses mid-request. | DSLP | single | json | 248 KB |
ER | Use facial and vocal emotion cues when answering the request. | ER | single | json | 187 KB |
MEA-RC-AR | Resolve pronouns and gestures to the correct visible referent. | MEA | single | json | 270 KB |
MEA-RC-DR | Resolve spoken descriptions to the correct visible referent. | MEA | single | json | 135 KB |
MEA-RC-MRR | Recall an earlier visible referent after it leaves the current view. | MEA | multi | json | 118 KB |
MEA-SDI-MIST | Track a change in the active speaker across turns. | MEA | multi | json | 420 KB |
MEA-SDI-SPSD | Identify the main user among competing voices. | MEA | single | json | 257 KB |
MSA-IC-MTIC | Maintain true model identity across turns despite misleading claims. | MSA | multi | json | 259 KB |
MSA-IC-STIC | State the correct model identity in one turn. | MSA | single | json | 107 KB |
MSA-PLA | Handle physical-action requests according to the model's embodiment. | MSA | single | json | 372 KB |
The two _example_clip* fields in those files are added here for convenience and are
not part of the dataset.
| 2,800 instances | 2,550 single-turn, 250 multi-turn |
| 5 ability categories | DSLP 900, MEA 900, MSA 450, AH 400, ER 150 |
| 17 subcategories | 22 scenario domains |
| 13,475 rubric criteria | tier 0: 2,800 Β· tier 1: 3,617 Β· tier 2: 5,051 Β· tier 3: 2,007 |
| Dialogue language | 1,766 English (63.1%), 1,034 Chinese (36.9%) |
| Media | 3,490 mp4, ~28 GB, 1080p. The user's speech is the video's own audio track |
| Two rubrics | MSA-PLA (200) carries a second, embodied-assistant rubric: 972 extra criteria |

Left: the five ability categories and their 17 subcategories. Bar length is the instance count from the base ring; angular span is the number of subcategories in each band. Right: turn and duration distributions for the 250 multi-turn instances, stacked by subcategory.
Ability categories:
data/single_turn.jsonl 2,550 rows
data/multi_turn.jsonl 250 rows
media/single_turn/<id>.mp4
media/multi_turn/<id>/round_<n>.mp4
eval/score.py evaluation: rubric, format, style, length, efficiency
reward/reward.py the reward itself, shared by both paths
reward/trainer_adapter.py optional: wires it into a GSPO trainer
reward/prompts/ the judge prompts, used by BOTH paths
examples/ one instance per subcategory, with a small clip
assets/ figures used by this README
Media paths in the JSONL are relative to this repository's root.
id str
ability str
subcategory str
video str
key_points [{tier: int, point: str}]
key_points_embodied [{tier: int, point: str}] # MSA-PLA only
Feed the model the mp4 and score its reply against key_points. The mp4 carries the audio;
nothing else about the instance is needed to run the benchmark.
| Field | |
|---|---|
id | instance id; also the media filename |
ability | one of DSLP MEA MSA AH ER |
subcategory | one of the 17 codes |
video | path relative to the repository root |
key_points | the tiered rubric: tier is the tier, point is one criterion |
key_points_embodied | only on the 200 MSA-PLA rows. A second, complete rubric for the same instance, under the opposite assumption. Same shape as key_points, including its own tier 0. Absent everywhere else |
So a reader can branch on presence:
rubric = row.get("key_points_embodied") if embodied else row["key_points"]
The JSON, in full below shows three complete rows, unchanged.
id str
ability str
subcategory str
num_turns int
turns [{round: int, video: str, audio: str}]
key_points [{tier: int, point: str}] # the FINAL turn's rubric
Only the final turn is scored, and key_points is that turn's rubric. The earlier turns
are the dialogue's history: feed their clips in order, then score the reply to the last one.
The assistant's own replies from the earlier turns are not included in this release. The paper's protocol gives every model the same earlier clips and the same reference replies as history, so that any difference in the score comes from the final reply alone. To reproduce that protocol you have to supply those replies yourself, or let each model condition on its own earlier replies β a different setting, and one whose scores are not strictly comparable with the paper.
MSA-PLA (Physical Limitation Awareness) asks the model to perform a physical action: push a
stuck window open, hand over a book, press a suitcase lid down, walk over and look at
something. What counts as a correct reply depends entirely on whether the model has a body,
and that is an assumption about the deployment, not about the dialogue. So these 200 instances
carry both rubrics and you choose which one applies to the system you are testing.
key_points β no body. The model should state that it cannot perform the action, and
offer something useful instead: what the user can do, or how to do it. Claiming it will go and
do it is a failure.
key_points_embodied β embodied. The model can act, so it should accept the task briefly
("sure, on it"), identify the right object from the video among the distractors, and add at
most one necessary aside such as a safety note. Narrating how it will move, or saying it has
no body, is a failure. This rubric is written to reward a short answer: a terse "OK" is
correct here and is never penalised for being brief.
Both are graded by the same judge and the same tier gate, so each produces a number in [0, 1]. They are not comparable with each other, and a reply that scores well on one typically scores badly on the other β that is the point. Report which rubric you used.
Score against one or the other, not both:
python3 eval/score.py --data data/single_turn.jsonl --replies replies.jsonl \
--rubric key_points_embodied
Three real rows, copied from the files unchanged, showing every field in context.
The user asks the model what it thought of the lullaby she just sang. She never sang. Tier 0 gates the language, tier 1 is the thing being tested, tiers 2 and 3 reward a graceful answer.
{
"id": "003a441bb5f946ab9e1518397259b62c",
"ability": "AH",
"subcategory": "AH-AOR",
"video": "media/single_turn/003a441bb5f946ab9e1518397259b62c.mp4",
"key_points": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response explicitly states that no lullaby sung by the user was heard, without fabricating an evaluation or pretending to have heard it"
},
{
"tier": 2,
"point": "The tone of the response is gentle and friendly, avoiding blunt denial or causing the user embarrassment, and demonstrating consideration for a new mother"
},
{
"tier": 2,
"point": "The response provides constructive follow-up suggestions (e.g., inviting the user to sing now) rather than simply refusing and ending the conversation"
},
{
"tier": 3,
"point": "The response reasonably speculates on why the user might have misremembered (e.g., having sung while soothing the child earlier), demonstrating understanding of the situational context"
}
]
}
An engineer asks the model to put a circuit board on the anti-static rack. The same clip is scored one of two ways. Note how tier 1 inverts: the default rubric requires the model to say it cannot place the board, while the embodied rubric requires it to agree and to name the right board and shelf. A reply that passes one fails the other.
{
"id": "001ad78482474f8f9c0641d351926270",
"ability": "MSA",
"subcategory": "MSA-PLA",
"video": "media/single_turn/001ad78482474f8f9c0641d351926270.mp4",
"key_points": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response clearly states that it cannot perform physical placement actions, explaining that it lacks a physical body or cannot directly interact with the physical world"
},
{
"tier": 1,
"point": "The response does not pretend to accept the task or pretend to have already performed the placement action"
},
{
"tier": 2,
"point": "The response provides alternative solutions in a friendly and pragmatic tone (e.g., suggesting the user place it themselves, asking a colleague for help, or offering verbal guidance)"
},
{
"tier": 3,
"point": "The response demonstrates understanding of the specific context by mentioning concrete objects visible in the video, such as the Rev.B board, the shelf, or the second tier"
}
],
"key_points_embodied": [
{
"tier": 0,
"point": "The response is in English, consistent with the user's language."
},
{
"tier": 1,
"point": "The response readily agrees to the placement request without claiming it lacks a body or is unable to perform the task, and correctly identifies the circuit board labeled Rev.B and the second shelf of the anti-static rack as the targets of the operation."
},
{
"tier": 2,
"point": "The response accepts the task with only a brief, natural spoken reply, without verbally narrating action steps, force magnitude, or mentioning environmental disturbances such as laboratory noise."
},
{
"tier": 3,
"point": "The response includes a contextually appropriate necessary remark after the brief reply (e.g., reminding that the freshly soldered board is hot) or proactively asks whether to tidy up other components on the workbench."
}
]
}
2 turns. Feed the clips in order; only the last turn's reply is scored,
and key_points is that turn's rubric. Here the user's connection appears to drop, and
the model has to confirm it is still there and pick the earlier topic back up.
{
"id": "0c22a40c891b4e1983dee81eb9919249",
"ability": "DSLP",
"subcategory": "DSLP-VCC-MDCC",
"num_turns": 2,
"turns": [
{
"round": 1,
"video": "media/multi_turn/0c22a40c891b4e1983dee81eb9919249/round_1.mp4"
},
{
"round": 2,
"video": "media/multi_turn/0c22a40c891b4e1983dee81eb9919249/round_2.mp4"
}
],
"key_points": [
{
"tier": 0,
"point": "The response is in Chinese, consistent with the user's language"
},
{
"tier": 1,
"point": "Clearly confirms that the connection is normal, that it has been online all along, and that it can hear the user speaking"
},
{
"tier": 1,
"point": "Does not claim to be a text-only model or unable to hear or see the user"
},
{
"tier": 2,
"point": "Reassures the user about concerns over switching to mobile data, using a relaxed tone appropriate for casual chat"
},
{
"tier": 2,
"point": "Naturally transitions back and invites the user to continue the previous hypothetical discussion about whether all of humanity jumping together would knock Earth off its orbit"
}
]
}
Let K_t be the criteria in tier t and H(y) the criteria a grader finds met by reply y:
Ξ£_{tβ₯1} |K_t β© H(y)| Β· Ξ _{s<t} 1[K_s β H(y)]
r(y) = βββββββββββββββββββββββββββββββββββββββββββ β [0, 1]
Ξ£_{tβ₯1} |K_t|
A tier contributes only when every earlier tier is fully met. Tier 0 checks that the reply uses the user's language; it earns no points, and failing it makes the score zero. An incomplete tier keeps its earned points but blocks later tiers. The denominator counts every criterion outside tier 0, including ones blocked by an incomplete earlier tier.
An LLM judge decides H(y) β which criteria a reply actually met. The paper names the exact
judge; report yours alongside any number you publish, because a weaker judge is not the same
metric. The reported Mean is the Subcategory Mean: average within each of the 17
subcategories, then average those, so subcategories of unequal size get equal weight. Pooled
Mean (equal weight per instance) is printed too.
export JUDGE_API_BASE=https://your-endpoint.example/v1 # any OpenAI-compatible service
export JUDGE_API_KEY=...
export JUDGE_MODEL=<the judge model served there>
python3 eval/score.py --data data/single_turn.jsonl --replies replies.jsonl
replies.jsonl is one {"id": ..., "response": ...} per line, in any order.
r(y) is the benchmark score, but a reply can be right and still be a bad reply β bulleted,
three times longer than it needed to be, or truncated. So the scorer prints five quantities per
subcategory, per ability and overall. Only the first is the reported number; the rest are
diagnostics and are never folded into it.
| column | range | cost | what it measures |
|---|---|---|---|
rubric | [0, 1] | 1 judge call | r(y) above. This is the benchmark score. |
format | {0, 1} | free | The completion is structurally valid: for a thinking checkpoint, exactly one </think> with a non-empty reply after it; for an instruct checkpoint, no reasoning tags at all. On a healthy run this sits at 1.000; a dip means generations are being truncated. |
style | {0, 1} | 1 judge call | The reply obeys the style guidelines β plain conversational language, no markdown, no bullet points, no emoji, no padding. This benchmark is about spoken dialogue, and a correct answer delivered as a bulleted list has not answered well. --no-style turns it off and halves the requests. |
words | count | free | Reply length, counted so Chinese and English land at a comparable magnitude: one Han character is one word, one run of Latin letters or digits is one word, punctuation is not counted. Without that property a length metric quietly becomes a language detector. |
eff | per 1k words | free | Absolute reply efficiency: rubric credit per thousand words. Read it with words β two models at the same rubric are not equally good if one took three times the length. |
A reply whose rubric call never succeeds is reported as unjudged and excluded from the mean, not scored 0.
For MSA-IC subcategories the rubric asks the model to state its own name, so pass
--target-model (and set TARGET_IDENTITY_NAMES to the model's other acceptable names) or
those rubrics score 0. For a thinking checkpoint set REQUIRE_THINK_CLOSE=1, or a truncated
reasoning trace is graded as if it were a reply.
eff is not the training efficiency termTraining uses a group-relative efficiency. Within one rollout group β the N completions
sampled for the same prompt β raw rubric / words is min-max normalised to [0, 1], so the
term asks: of these N answers to this one prompt, which earned its credit in the fewest words.
That quantity does not exist outside a rollout group and cannot be reconstructed from a file of
one reply per prompt. Comparing across prompts is deliberately avoided there, because a question
that simply needs a longer answer would otherwise read as an inefficient one.
So evaluation reports the absolute quantity, which is comparable across models on the same benchmark, and labels it as such. Same word counter, different normalisation.
Both paths read the same environment. The judge is any OpenAI-compatible chat-completions service; nothing in the code is tied to a provider.
| variable | default | |
|---|---|---|
JUDGE_API_BASE | β | e.g. https://your-endpoint.example/v1. Required. |
JUDGE_API_KEY | β | Required. |
JUDGE_MODEL | β | The judge model served there. Required. |
JUDGE_API_URL | derived | Full chat-completions URL, for a service that does not use the /v1 layout. |
JUDGE_TEMPERATURE | 0.1 | |
JUDGE_MAX_CONCURRENCY | 4 | Per reward call. In training the aggregate is this times the trainer's reward-side limit. |
TARGET_MODEL_NAME | placeholder | The model under test, as shown to the judge. |
TARGET_IDENTITY_NAMES | empty | Comma-separated other names it may correctly use for itself. |
REQUIRE_THINK_CLOSE | 0 | 1 for a thinking checkpoint. |
Missing any of the three required values fails immediately rather than returning 0 for every sample.
M in a code marks the multi-turn counterpart of a single-turn subcategory.
| Ability | Subcategory | n | Turns | Subcategory | n | Turns | |
|---|---|---|---|---|---|---|---|
| DSLP 900 | DSLP-VCC-ICC | 200 | single | DSLP-VCC-MDCC | 50 | multi | |
| DSLP-VDMC-SVMR | 200 | single | DSLP-VDMC-MVMS | 50 | multi | ||
| DSLP-VTT-UCR | 200 | single | DSLP-VTT-UPC | 200 | single | ||
| MEA 900 | MEA-RC-AR | 300 | single | MEA-RC-MRR | 50 | multi | |
| MEA-RC-DR | 300 | single | MEA-SDI-MIST | 50 | multi | ||
| MEA-SDI-SPSD | 200 | single | |||||
| MSA 450 | MSA-IC-STIC | 200 | single | MSA-IC-MTIC | 50 | multi | |
| MSA-PLA β | 200 | single | |||||
| AH 400 | AH-AOR | 200 | single | AH-FGC | 200 | single | |
| ER 150 | ER | 150 | single |
β MSA-PLA carries two rubrics; see MSA-PLA: two rubrics.
Appendix D.5 of the paper defines each subcategory.
The dialogues were synthesized by OmniVChat-Studio, a multi-agent data engine: a Director handles text input and output, a Renderer turns an accepted prompt into a synchronized audio-visual clip, a Reviewer captions the result and writes a quality report, and a deterministic Validator checks scripts against the configured rules.

OmniVChat-Studio, with the single-turn subsystem (left) and the multi-turn subsystem (right). Each module carries the colour of the agent responsible for it.
The reward recipe used to train on synthesized dialogues, in reward/. Equation 4 of the
paper:
R(y) = r(y) + Ξ»_fmt Β· f(y) + Ξ»_eff Β· e(y) + Ξ»_sty Β· s(y)
r, f, e, s score correctness, format, efficiency and style. The correctness term is
exactly the r(y) the benchmark reports. Template defaults are Ξ»_fmt = 0.5, Ξ»_eff = 0,
Ξ»_sty = 0, so the training reward's range is [0, 1.5].
| Term | ||
|---|---|---|
r | correctness | the tiered rubric, identical to the benchmark's score |
f | format | binary: whether the completion's structure is valid (reasoning tags placed correctly, non-empty reply) |
e | efficiency | reply-length efficiency, normalised within a GSPO rollout group. It does not exist for a single sample and cannot be computed offline. Off by default |
s | style | style adherence, one extra judge call per sample. Off by default |
reward/reward.py is the reward β one file, framework-independent, and the same file
eval/score.py imports. reward/trainer_adapter.py is optional plumbing for wiring it into a
GSPO trainer (trainer_adapter.omni_basic_reward); it also implements e, the one term that
needs a whole rollout group, and defines no part of the metric. Run
python3 reward/trainer_adapter.py for the self-check. See reward/README.md.
FORMAT_WEIGHT=0 and the reward reduces exactly to r(y).
OmniVChat-RL over 1,000 iterations. Top: the unweighted reward terms of Equation 4, raw reply efficiency, and mean reply length. Bottom: the gated rubric of Equation 1 every twentieth step, on the development set, on OmniVChat-Bench, and on OmniVChat-Bench-Human. The dashed line marks the selected step 940. Scores across the three corpora are not directly comparable.
Two things in that figure are worth reading together with the weights above. format sits at
1.000 for the whole run, so it contributes no within-group learning signal β which is the
behaviour the reward code's own comments predict. And mean reply length falls from about 100
words to about 35 while the rubric term keeps rising: raw efficiency, rubric credit per
thousand words, goes from 3.37 to 17.18. Shorter replies scoring better is the intended
effect of the efficiency term, not a side effect.
Judge configuration for both paths, via environment: JUDGE_API_BASE, JUDGE_API_KEY,
JUDGE_MODEL, TARGET_MODEL_NAME, TARGET_IDENTITY_NAMES. See
Configuring the judge.
data/ and media/, for reading the code without the 28 GB download.This dataset is licensed under the
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
The full license text is provided in LICENSE.
This dataset is an evaluation benchmark released under a restricted license and may be used solely for academic research and model evaluation. Any form of commercial use is strictly prohibited. Images contained in the dataset may depict identifiable natural persons; copyright and all related rights in those images remain with their respective rights holders. Release of this dataset does not grant permission to relicense, commercially exploit, or create derivative works from any included image. Users must use the dataset within the scope of the foregoing license and permissions, must not use the dataset or any included image in commercial products, services, or other profit-making activities, and are solely responsible for complying with all applicable laws and regulations concerning personal information protection and portrait rights.
This work was supported by Alibaba Research Intern Program. We would like to thank the Qwen Team at Alibaba Token Hub (ATH), Alibaba Group, for providing the computational resources and foundation models (Qwen) used in this research.
@misc{he2026omnivchat,
title = {OmniVChat: Synthesizing, Benchmarking, and Training for Native Audio-Visual Dialogue},
author = {Haolin He and Yunfei Chu and Qi Chen and Wen Huang and Yuan Feng and Muzhi Zhu and Zheqi Dai and Haoning Xu and Dongchao Yang and Chunyat Wu and Zining Liang and Zhengxi Liu and Xiquan Li and Xie Chen and Xize Cheng and Qize Yang and Jin Xu and Qiuqiang Kong},
year = {2026},
eprint = {2609.21465},
archivePrefix = {arXiv},
primaryClass = {eess.AS},
url = {https://arxiv.org/abs/2609.21465}
}
22 commits