Repository navigation
Conversation
There was a problem hiding this comment.
馃煛 Changes recommended
CLI dtype overrides break checkpoint-precision preservation, and the fixture cache can reuse stale artifacts.
2 open findings
What changed in this PR
Adds OpenVINO export support for DSpark drafts with vanilla Markov heads and MiniCPM-V 4.7 targets.
Changes:
- Exports dense or Top-K Markov-head sidecar models.
- Adds DSpark validation, metadata, CLI options, and precision handling.
- Adds extensive export, parity, compression, and CI coverage.
| File | Description |
|---|---|
optimum/鈥媏xporters/鈥媜penvino/鈥媎flash_utils.py |
Defines DSpark configuration validation and interfaces. |
optimum/鈥媏xporters/鈥媜penvino/鈥媘odel_patcher.py |
Implements the DSpark backbone and Markov exporters. |
optimum/鈥媏xporters/鈥媜penvino/鈥媘odel_configs.py |
Adds Markov model export contracts. |
optimum/鈥媏xporters/鈥媜penvino/鈥媔nput_generators.py |
Generates Markov export inputs. |
optimum/鈥媏xporters/鈥媜penvino/鈥媍onvert.py |
Splits and annotates DSpark exports. |
optimum/鈥媏xporters/鈥媜penvino/鈥媌ase.py |
Adds precision-preservation configuration. |
optimum/鈥媏xporters/鈥媜penvino/鈥媉_main__.py |
Integrates DSpark export and tokenizer handling. |
optimum/鈥媍ommands/鈥媏xport/鈥媜penvino.py |
Adds --dspark-top-k. |
tests/鈥媜penvino/鈥媢tils_tests.py |
Creates tiny DSpark fixtures. |
tests/鈥媜penvino/鈥媡est_dflash.py |
Tests parity, metadata, and precision. |
tests/鈥媜penvino/鈥媡est_exporters_cli.py |
Tests CLI packages and tokenizer omission. |
docs/鈥媠ource/鈥媜penvino/鈥媘odels.mdx |
Documents supported DSpark checkpoints. |
.github/鈥媤orkflows/鈥媡est_openvino_preview_models.yml |
Adds MiniCPM-V metadata validation. |
馃 Review effort: Balanced
馃挕 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
rkazants
left a comment
There was a problem hiding this comment.
Please also provide proper PR descriprion with full standalone code snippets for models export, inference using Openvino GenAI. How to set up environment to test it
rkazants
left a comment
There was a problem hiding this comment.
btw, did you cherry-pick my changes for CB support?
|
Sure, will do so when GenAI PR is also ready
|
|
No. It鈥檚 a SDPA-only version that is subject to change together with DFlash2 support which is expected to come with CB
Note that the backbone is a pure DFlash.
|
ce0e7ec to
5daa20d
Compare
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
381a670 to
e64644b
Compare
|
Two follow-ups for after this PR and #1983 merge. 1. Rename 2. DSpark drafts with a pruned vocabulary. Several published DSpark drafts (which is also true for some DFlash drafts) score only part of the target vocabulary, as Eagle-3 drafts do:
This PR doesn't support them. It supports the DeepSpec format of the MiniCPM-V 4.7 drafts, which reuse the target's
With this PR, these checkpoints fail when loaded (missing Supporting them changes the draft contract with GenAI: the draft applies its own Not sure who's the decision maker whether the above should be supported. |
Export the Markov head next to the DFlash backbone, as the dense Markov step or, with --dspark-top-k, as a Top-K candidate scorer. The head is not weight-compressed, and markov_rank=0 drafts export as plain DFlash drafts. Co-authored-by: Cursor <cursoragent@cursor.com>
The drafts run with the target's tokenizer; without a tokenizer in the checkpoint, Transformers 5 builds and saves a placeholder one. Co-authored-by: Cursor <cursoragent@cursor.com>
Export the Markov head as openvino_markov_head_model.xml with two computations over the same weights: the dense Markov step and the Top-K lattice, whose K (64 by default) is held by a single TopK so the runtime can change it. The lattice takes the rows of several draft blocks packed back to back and delimited by subsequence_begins. MarkovHeadForExport defines this first-order Markov head contract, and the DSpark vanilla head implements its transition scores. The runtime selects the computation, so --dspark-top-k is removed. Co-authored-by: Cursor <cursoragent@cursor.com>
The tiny DSpark draft runs with the tiny Qwen3 target through the continuous batching pipeline, like the DFlash cases. GenAI without DSpark support runs it as a plain DFlash draft, so the case needs no new version gate. The preview workflow runs the DSpark tests in test_dflash.py and test_genai.py against the nightly GenAI. Co-authored-by: Cursor <cursoragent@cursor.com>
The custom draft loader pointed config.auto_map at model_patcher.py and loaded it as remote code, so transformers required every package that file imports, diffusers among them. Exporting a DFlash or DSpark draft then failed without the diffusers extra, which the DFlash CI step does not install. Load the DFlash and DSpark export classes directly, as in huggingface#1983; Eagle3 drafts keep the auto_map loader. Co-authored-by: Ofir Zafrir <ofir.zafrir@intel.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Qwen3OpenVINOConfig declares the Markov head of a DSpark draft as a behavior (SUPPORTED_BEHAVIORS, with_behavior, get_model_for_behavior), and _get_submodels_and_export_configs adds declared models with a generic loop. - The head's rt_info is written by _add_dflash_mode_to_rt_info through its existing call; _add_dflash_interface_to_rt_info is removed, and so is the redundant hidden-state condition in _save_model. - Eagle3DummyGenerator generates the Markov head inputs, replacing DSparkMarkovDummyGenerator. - The generic CLI export tests cover qwen3_dspark, and the preview CI step, renamed to GenAI speculative decoding validation, runs test_exporters_cli.py. Co-authored-by: Cursor <cursoragent@cursor.com>
521fb9b to
33ad777
Compare


What does this PR do?
Adds export of DSpark drafts, DFlash drafts with a Markov head that adjusts each drafted token's logits based on the previous token. Until now, drafts with a Markov head (
markov_rank > 0) were rejected.The draft backbone is exported as for DFlash. The Markov head is exported next to it as one model,
openvino_markov_head_model.xml, that holds two computations over the same weights: a dense Markov step and a Top-K candidate scorer. OpenVINO GenAI selects one of them when it loads the draft, so the export has no DSpark-specific options. Only the vanilla Markov head is supported for now. It is never weight-compressed, so it keeps its original precision unless--weight-format fp16/fp32is given.Runtime support: openvinotoolkit/openvino.genai#4660. The draft backbone follows the current DFlash draft contract, which is planned to change with continuous batching support for DFlash-family drafts. The Markov head model is built for compatibility with continuous batching already: the candidate scorer takes the draft blocks of several requests packed back to back.
Also:
How to test
Environment (Python 3.11+). Until openvinotoolkit/openvino.genai#4660 is merged, OpenVINO GenAI is built from its branch, which needs CMake 3.26+ and a C++ compiler:
Export the target and the DSpark draft:
Once #1983 is merged, the draft export needs neither option for a Hub model ID: DFlash and DSpark drafts are then loaded directly instead of through remote code, and their task is inferred. A local checkpoint folder still needs
--task text-generation-with-past, because the task cannot be inferred from a local folder.optimum-cli export openvino --model openbmb/MiniCPM-V-4.7-1B-DSpark minicpm-v-4.7-1b-dspark-ovRun with OpenVINO GenAI:
On GPU, the Top-K candidate scorer needs openvinotoolkit/openvino#38845 to be fast. With the current nightly, its TopK over the vocabulary falls back to a generic GPU kernel, and the draft is slower than the target alone.
Tests
Validated end to end with OpenVINO GenAI on MiniCPM-V-4.7-1B and its DSpark draft: with both computations, the outputs and accepted tokens are identical to those of the previous revision's separate Markov head models, which were also validated with MiniCPM-V-4.7-35B-A3B-DSpark. Unit tests use a tiny generated DSpark checkpoint and cover numerical parity of both computations, packed draft blocks of different lengths, changing K, metadata, precision, CLI export, and drafts without a Markov head still exporting as plain DFlash drafts. A GenAI test runs the tiny DSpark draft with a tiny Qwen3 target through the continuous batching pipeline and checks that greedy outputs match the target alone; the preview models workflow runs the DSpark tests against the GenAI nightly.
Before submitting