Skip to content

feat(perf): support composite model generation benchmarking#1059

Open
xieofxie wants to merge 8 commits into
mainfrom
hualxie/infer_automodel
Open

feat(perf): support composite model generation benchmarking#1059
xieofxie wants to merge 8 commits into
mainfrom
hualxie/infer_automodel

Conversation

@xieofxie

@xieofxie xieofxie commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Updates winml perf to support composite models (e.g. Qwen decoder-only) loaded via WinMLCompositeModel.from_onnx, benchmarked with model.generate() using text prompts — matching eval.py's composite model CLI pattern.

Changes

CLI

  • --model now accepts multiple=True with role=path syntax for composite models
    (e.g. -m decoder_prefill=prefill.onnx -m decoder_gen=gen.onnx)
  • Added --model-id for HF config/tokenizer resolution (ported from eval.py)
  • --prompt and --max-new-tokens now work for WinML composite generation (previously genai-only)

Engine

  • _resolve_model_path() — ported from eval.py for consistent composite -m role=path parsing
  • _load_model() — handles dict model_pathWinMLAutoModel.from_onnx(dict, hf_config=...)
  • _is_generative_composite — detects WinMLDecoderOnlyModel (e.g. Qwen)
  • _run_generation() — benchmarks via model.generate() with tokenized prompt, reports TTFT, decode tokens/sec, TPOT

Data classes

  • BenchmarkConfig — added model_path, hf_model_id, prompt, max_new_tokens
  • GenerationBenchmarkResult — LLM-style metrics matching GenaiBenchmarkResult's structure
  • display_generation_report() — console output for generation results

Usage

winml perf \
  -m decoder_prefill=output/prefill/model.onnx \
  -m decoder_gen=output/gen/model.onnx \
  --model-id Qwen/Qwen3-0.6B \
  --task text-generation \
  --prompt "Hello, how are you?" \
  --max-new-tokens 50 \
  --iterations 10 --warmup 2

Testing

All existing tests pass (49 CLI tests, 12 composite tests, 41 genai perf tests, 15 auto_onnx tests, 5 qwen3 composite tests).

Hualiang Xie added 2 commits July 6, 2026 15:13
Add support for benchmarking composite models (e.g. Qwen decoder-only)
via model.generate() with text prompts, matching eval.py's composite
model CLI pattern.

Changes:
- CLI: --model now accepts multiple role=path pairs for composite models
  (e.g. -m decoder_prefill=p.onnx -m decoder_gen=g.onnx)
- CLI: add --model-id for HF config/tokenizer resolution
- CLI: --prompt and --max-new-tokens now work for winml composite generation
- BenchmarkConfig: add model_path, hf_model_id, prompt, max_new_tokens
- _resolve_model_path: port from eval.py for composite -m parsing
- _load_model: handle dict model_path via WinMLAutoModel.from_onnx
- _is_generative_composite: detect WinMLDecoderOnlyModel
- _run_generation: benchmark via model.generate() with tokenized prompt
- GenerationBenchmarkResult: LLM-style metrics (TTFT, decode tps, TPOT)
- display_generation_report: console output for generation results
@xieofxie xieofxie requested a review from a team as a code owner July 6, 2026 07:13
Comment thread src/winml/modelkit/commands/perf.py Fixed
Comment thread src/winml/modelkit/commands/perf.py Outdated
Comment thread src/winml/modelkit/commands/perf.py
Comment thread src/winml/modelkit/commands/perf.py Outdated
Comment thread src/winml/modelkit/commands/perf.py Outdated
Comment thread src/winml/modelkit/commands/perf.py Outdated
Comment thread src/winml/modelkit/commands/perf.py
Hualiang Xie added 5 commits July 6, 2026 16:21
- Move _resolve_model_path to cli_utils.resolve_model_path (shared by eval + perf)
- Extract _DEFAULT_PROMPT constant, change BenchmarkConfig.prompt to str | None
- Add apply_template support for composite models via tokenizer.apply_chat_template
- Switch _is_generative_composite to capability-based hasattr check
- Align display_generation_report format with display_genai_report (TTFT table)
- Fix CodeQL empty except with explanatory comment
- Update tests for --model-id requirement on ONNX inputs
…ntimes

Extract shared GenerationBenchmarkResult dataclass and
display_generation_report into _perf_generation.py.  Both
_perf_genai.py (onnxruntime-genai bundles) and perf.py
(WinML composite models) now use the same result class and
display function.

The shared result includes all fields from both runtimes
(prefill_mean_ms, context_length, avg_token_latency_ms)
with defaults of 0 when unused.  Runtime-specific JSON
fields (compile, apply_template, bundle_dir) go into
extra_info which is merged into benchmark_info in to_dict().
Tests that pass .onnx files via -m now include --model-id,
matching the shared resolve_model_path validation that requires
it for preprocessor/config resolution.
Add require_model_id_for_onnx parameter to shared resolve_model_path.
eval keeps it required (needs HF config), perf passes False since it
can benchmark plain ONNX without preprocessor resolution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants