Repository navigation
Add vLLM image support and prompt/image ablation knobs (port of #347 to main) - #439
Open
donovanclay wants to merge 9 commits into
Open
donovanclay wants to merge 9 commits into
donovanclay wants to merge 9 commits into
Conversation
Image requests render through the tokenizer's chat template, which emits the model's own image placeholders, and go to vLLM as multi_modal_data. Lazy image references are resolved the way the other multimodal providers resolve them. - max_images raises vLLM's per-prompt image cap (default 1); an oversized prompt fails with the knob named instead of failing its whole batch. - chat_template_kwargs reaches apply_chat_template (e.g. enable_thinking). - add_bos_token=False and logprobs() refuse image requests rather than silently dropping the images. Ported from #347 onto main's vision layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… text path multimodal now defaults to None and is detected from the config (auto_map, a vision sub-config, or a known image-text-to-text architecture). A multimodal HF directory previously fell through to AutoModelForCausalLM and died with an error naming neither cause nor fix. A remote-code repo read without trust_remote_code now raises with the flag named. The text-only generate path read request.prompt, which a CHAT request leaves empty, so it tokenized to zero tokens and failed inside attention. It now applies the chat template. Ported from #347. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A trailing newline (easy to introduce in a Beaker secret) makes an illegal Authorization header, which the openai SDK reports as a generic 'Connection error' -- indistinguishable from an outage, and it silently zeroed a full dense_caption run. Ported from #347. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`-o sampling_params.max_tokens=64` arrived as a nested dict and was applied as a task override, replacing the task's SamplingParams with the bare dict and dropping every field it omitted (gsm8k lost its stop_sequences). The runner now routes it through sampling_overrides, which preparation merges with replace(); unknown fields are rejected by name. TaskConfig refuses a raw dict, since by __post_init__ there is nothing left to merge against. Ported from #347. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prompt_style picks the prompt convention: molmo (default, mm_olmo's SFT format), neutral (no style tag plus the short-answer instruction published VLM numbers use), or cot (reason, then a final 'Answer:' line). Without neutral, chat-tuned models answer in sentences and exact-match scores collapse (Qwen3-VL-4B ChartQA 13.9 -> 84.2). image_mode picks what stands in for the image: real (default), none, or caption (from a caption_source JSONL), so real/none/caption runs split error between perception and knowledge. - Variants: :neutral on the short-answer image-QA tasks and mmmu; mmmu:cot (last-Answer extractor, max_tokens 2048); :text_only / :oracle_caption on mmmu and both charxiv tasks. - CharXiv also gains cot_cue and charxiv_templates. - Only ImageQATask honours the knobs; the other vision families refuse them, a missing caption fails rather than falling back to text-only, and the mmmu_pro vision setting refuses imageless modes. - The fields enter TaskConfig.to_dict only when non-default, so existing task hashes are unchanged. Ported from #347 onto main's vision layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aptions tools/olmo_core_to_hf/export.py converts an OLMo-core (or mm_olmo) DCP step directory into a released-Molmo2 HF directory, which vLLM loads directly. The weight mapping is OLMo-core's multimodal_lm_state_dict_to_hf; --verify compares an export against the reference repo tensor by tensor. tools/oracle_captions/generate.py writes the caption_source JSONL for the image_mode=caption ablation, captioning each distinct image once through a content-keyed disk cache. Ported from #347 onto main's olmo_core_vlm package layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The caption_source format stays documented; the generator can land separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They are narrow CharXiv probe tools rather than general eval settings and can land separately. The charxiv :text_only / :oracle_caption variants stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 of 9 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Ports #347 (opened against
vision) ontomain.mainalready has the vision stack, restructured by the #316–#324 series (evals/vision/,providers/olmo_core_vlm/), so this is a re-implementation on that layout rather than a cherry-pick. Measurements and the review discussion are in #347.What it adds
VLLMProvider. Image requests render through the tokenizer's chat template, which emits the model's own image placeholders, and go to vLLM asmulti_modal_data. Lazy image references resolve throughcommon.images.resolve_images, like the other multimodal providers.supports_images = True, so the harness routes vision tasks to it.max_imagesraises vLLM's per-prompt cap (default 1). An oversized prompt fails with the knob named instead of failing its whole batch inside vLLM.chat_template_kwargsis forwarded toapply_chat_template(e.g.enable_thinking).add_bos_token=Falseandlogprobs()refuse image requests instead of silently dropping the images.olmo_coreon short-answerchart_qa, 4.8× on long-decodecharxiv_reasoning. HF-vs-vLLM parity over 8 image-QA tasks: mean |Δ| 0.29, max 0.69, signs mixed.HuggingFaceProviderfixes.multimodalnow defaults to auto-detection from the config (auto_map, a vision sub-config, or a known image-text-to-text architecture). A remote-code repo read withouttrust_remote_coderaises an error that names the flag.request.prompt, which CHAT requests leave empty, so it fed zero tokens into the model.prompt_styleandimage_modeon the image-QA tasks (evals/vision/tasks/prompting.py). Both default to the published benchmark, and both were measured on Add vllm image support #347's branch:prompt_style=neutraldrops mm_olmo's style tag and asks for a short answer. Without it, non-Molmo models answer in sentences and exact match fails. Qwen3-VL-4B-Instruct on full sets vs the Molmo2 paper's numbers::neutralmmmu:cotasks for reasoning with a finalAnswer:line and scores the last one. MMMU is a reasoning benchmark, and the default prompt forbids reasoning. Qwen3-VL-4B goes 49.56 → 57.89 at 2048 tokens (60.11 at 8192). That is still about 7 points under the published 67.4, so it narrows the gap without reproducing it.image_mode:nonedrops the image andcaptionsubstitutes a description fromcaption_source, a JSONL of{"example_id", "caption"}. Comparing the two against the real image splits error between perception and knowledge. Molmo v9:MMMU is limited by the language model, CharXiv descriptive by perception, and CharXiv reasoning mostly by reasoning.
Variants:
:neutralon the short-answer tasks andmmmu;mmmu:cot;:text_only/:oracle_captiononmmmuand bothcharxiv_*tasks.Only
ImageQATaskhonours these fields. Every other vision family refuses them, so an unmodified benchmark is never reported under an ablation label.The new fields enter
TaskConfig.to_dictonly when non-default, so existing task hashes are unchanged.sampling_paramsoverrides merge instead of replacing. Onmain,-o sampling_params.max_tokens=64replaces the task'sSamplingParamswith the bare dict, e.g. gsm8k loses itsstop_sequences. Reproduced onmainbefore the fix.OPENAI_API_KEYis stripped. A trailing newline in the key surfaced as a generic "Connection error" from the judges.tools/olmo_core_to_hf/export.py. Converts an OLMo-core DCP checkpoint into a released-Molmo2 HF directory, so vLLM can run our checkpoints.--verifycompares the export with the reference repo tensor by tensor.Deliberately not ported from #347
vision_backbone.key compat inolmo_core_vlmmain(pinned to OLMo-corevision) it would break every DCP load. Better to land it together with #834.strip_reasoning,inference/reasoning.py,metadata["reasoning"]mainalready has task-levelstrip_thinking(-o strip_thinking=true), which strips</think>traces before scoring and keepsoriginal_textin predictions.chartgymtaskcot_cue,charxiv_templates(CharXiv)tools/oracle_captions/generate.pycaption_sourceis a plain JSONL ({"example_id", "caption"}), and the generator can land separately.full_weight(), batch-error traceback, derived-oallowlistmain.Type of Change
Testing
Unit tests pass locally (
pytest tests/ --ignore=tests/integration/)Integration tests pass (if applicable)
New tests added for new functionality
Full unit suite, compared against unmodified
main: 2964 passed on this branch vs 2879 onmain(before the CharXiv knobs and their 7 tests were dropped). The same 14 tests fail on both because of the local environment (nomodal, tree-sitter grammar, one tokenizer test), so there are no regressions.New tests (78):
multi_modal_data, lazy refs, themax_imagesandlimit_mm_per_promptinterplay, the bos/logprobs guards. These run against the existing fake LLM, with no vLLM install needed.prompt_style/image_modemodes and their failure modes, the refusal in non-image-QA families, and task-hash stability.sampling_paramsrouting.ruff format --check,ruff checkandty check src/are clean.tyreports the same 29 pre-existing diagnostics as unmodifiedmain, and none new.Exporter, run end to end on an OLMo-core stage-2 DCP checkpoint: its output is bitwise-identical to Add vllm image support #347's version of the tool (706/706 tensors, same configs).
--verifymatches the released Molmo2-4B structure.GPU smoke from this branch (
olmo-eval beaker launch, 1 GPU each on saturn):molmo2-4bpreset)chart_qa(100)chart_qa(100)chart_qa:neutral(100)mmmu_pro(60)The Molmo2-on-vLLM leg needs
-o provider.trust_remote_code=true -o provider.kwargs.limit_mm_per_prompt.video=0.Not re-run here: Add vllm image support #347's full throughput sweep and 8-task parity table.
Checklist
🤖 Generated with Claude Code