Skip to content

Qualcomm AI Engine Direct - [GenAI Pipeline] Multimodal LLM & LLM Preparation and Quantization - #23050

Open
DannyYuyang-quic wants to merge 1 commit into
pytorch:mainfrom
CodeLinaro:dev1/danny/pr-A1
Open

DannyYuyang-quic wants to merge 1 commit into
pytorch:mainfrom
CodeLinaro:dev1/danny/pr-A1

Conversation

@DannyYuyang-quic

@DannyYuyang-quic DannyYuyang-quic commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Summary

First PR of Phase 2 Stream A. This PR makes the GenAI Pipeline runnable for
LLM and MLLM models through the front half of the flow:

CLI -> model lookup -> source transforms -> model preparation
    -> dataset-backed calibration -> quantization -> save QDQ model

examples/ and the legacy llama.py path remain unchanged. Compilation and
device inference remain in Stream B / PR-A2.

What's Included

CLI Entry Point: cli.py

Adds a GenAI Pipeline CLI that resolves model, dataset, and quantization options, builds PipelineContext, and invokes model preparation and quantization. FP16 omits quantization; QAT, embedding quantization, and attention sink are rejected for now.
The rejected feature will be raised in following PR.

Registry-Backed Model lookup: model_lookup.py

Maps a user-facing model name to the model-specific inputs consumed by the pipeline. Callers resolve one registry config, then derive from that same entry:

  • Model construction: component and graph keyed constructors, including
    decoder decode/quantize graphs, optional prefill graphs, and multimodal
    embedding variants.
  • Source preparation: component-keyed state-dict weight transforms and
    module G2G transforms, plus the Hugging Face state-dict loader when needed.
  • Pipeline configuration: component sharding, quantization dtypes and
    recipe classes, and LLM or MLLM loader/quantizer adapters.

This centralizes model-family branching at the registry boundary; the model preparation and quantization stages consume only the derived component and graph keyed configuration.

LLM and Multimodal LLM model components: model_components/

Adds pipeline import surfaces for decoder, token embedding, and encoder components over existing examples implementations.

Module G2G Transforms: source_transform/:

Collects existing llama.py transformations into reusable pipeline functions:

  • Weight transforms.
  • Model graph-to-graph (G2G) transforms.

LLM and MLLM Model Loading and Preparation: strategies/model_preparation/:

ExecuTorchModelPreparationStrategy implements the shared preparation flow:

  1. Load one weighted module per component and graph variant.
  2. Read per-graph metadata.
  3. Build model-native example inputs for each graph.
  4. Select one weight-sharing module per component.
  5. Apply component-level module transforms.
  6. Load the tokenizer.
  7. Build the model-specific inference helper used by quantization, if any.
  8. Optionally export the tokenizer for runtime.
  9. Extract a tokenizer chat template, falling back to extra_options.

LLMLoaderAdapter handles text decoders; MLLMLoaderAdapter handles multimodal models. The default adapter owns shared tokenizer and transforms logic.

Dataset stack: datasets/

Adds typed dataset options, lookup, loaders, calibration adapters, and LLM/MLLM collators. It supports random fallback data, lm-eval samples, JSON messages, Hugging Face chat datasets, and multimodal messages.

generate_calibration_data() now receives example_inputs explicitly because collators require the calibration-graph signature.

Quantization: strategies/quantization/:

ExecuTorchQuantizationStrategy implements native PTQ for component and graph keyed models:

  1. Create one QNN quantizer per component graph.
  2. Export every graph variant and prepare it with observers.
  3. Initialize observers for deploy graphs.
  4. Build real calibration inputs through the calibration data adapter.
  5. Run PTQ calibration on graphs that consume real data.
  6. Convert prepared graphs to QDQ modules.
  7. Propagate encodings from quantize graphs to deploy graphs.
  8. Remove quantize-only graphs from the output.

Decoder and token embedding use separate quantize and deploy graphs; encoders use one shared graph. Encodings are propagated before lowering.

Quantizer creation belongs to the strategy; LLM/MLLM adapters own only model-family-specific export, preparation, conversion, and calibration.

Quantization Helpers: quant_utilities.py:

Provides QNN quantizer construction, recipe application, QDQ saving, logits/KV-cache attributes, and encoding propagation. KV-cache override is enabled only when n_cache_layers is provided.

Quantization Output

QuantizationOutputConfig now returns component and graph keyed GraphBundle objects. Each bundle carries the quantized graph module, export inputs, metadata, and optional quantized IO dtypes.
Quantize-only graphs are removed after their encodings have been propagated, so downstream compilation sees only deployment graphs.

Tests

Covers CLI/config construction, source transforms, datasets and collators, loader adapters, model preparation, quantization adapters and strategy, and preparation/quantization stage integration.

PR Review Checklist

  • All dependencies are injected via constructor with sensible defaults - Yes.
  • All external calls are behind injectable interfaces - Yes
  • Hugging Face, TokenizerWrapper, torch.export, PT2E, QNN quantizer construction, dataset
    loading, and calibration execution sit behind adapters or lookup-created
    callables.
  • Unit tests cover the new public behavior - Yes.
  • Docstrings on public classes and methods - Yes.
  • Type annotations on function signatures - Yes.
  • Logging follows the strategy in the LLD - Yes; info for stage-level progress, debug for per-step details, warning for degraded/normalized CLI behavior. No existing behavior changed - Yes
  • examples/ is not modified and llama.py remains the reference path. - Yes

Related PRs

Phase 2 flow. PR-A1 and PR-B1 are independent and can land in either order.
PR-B2 depends on PR-B1. PR-A2 depends on PR-A1 and PR-B2, and closes Phase 2 by wiring the runner and adding the parity test that gates Phase 3 deletion of the legacy flow.

PR-A1 (this PR) ────────────────┐
                                ├─► PR-A2
PR-B1 ───────────► PR-B2 ───────┘

Phase 1 (merged):

Phase 2:

  • PR A1: Model registry, model_lookup, CLI, Multimodal LLM & LLM model preparation,
    dataset-backed calibration, component/graph-aware quantization, and encoding
    reconciliation. [This PR].
  • PR B1: Compilation foundation: Qualcomm AI Engine Direct - [GenAI Pipeline Phase 2] PRB1 - Compilation foundation #22846
  • PR B2: Multi-graph lowering, weight sharing, sharding, and spill-fill.
    Depends on PR-B1.
  • PR A2: Device-runner adapter, pipeline-runner wiring, README, and E2E parity
    test. Depends on PR-A1 and PR-B2.

Test plan

Run only tests added in this PR:

python -m pytest \
  backends/qualcomm/genai_pipeline/tests/strategies/model_preparation/ \
  backends/qualcomm/genai_pipeline/tests/strategies/quantization/ \
  backends/qualcomm/genai_pipeline/tests/source_transform/ \
  -v

Result:

126 passed, 2 subtests passed in 11.59s

Run all genai_pipeline tests:

python -m pytest backends/qualcomm/genai_pipeline/tests/ -v

Result:

238 passed, 13 subtests passed in 14.37s

Run all tests with coverage:

python -m pytest backends/qualcomm/genai_pipeline/tests/ \
  --cov=backends/qualcomm/genai_pipeline \
  --cov-config=backends/qualcomm/.coveragerc \
  --cov-report=term-missing

Result:

238 passed, 13 subtests passed in 17.41s

Confirm the legacy flow is unaffected:

python -c "
from executorch.examples.qualcomm.oss_scripts.llama.llama import _build_parser, export_llama
from executorch.examples.qualcomm.oss_scripts.llama.wrappers import MultiModalManager, HybridAttentionSinkEvictor
print('LEGACY IMPORTS OK')
"

Result:

`LEGACY IMPORTS OK`

…Quantization

Add the LLM/MLLM GenAI pipeline integration for model preparation, dataset-driven calibration, and ExecuTorch quantization.

Summary:
  - Add the GenAI pipeline CLI and stage context wiring.
  - Add model registry lookup helpers for configs, graph builders, source
    transforms, checkpoint loaders, quantization settings, and adapters.
  - Add component-aware LLM/MLLM model preparation adapters for decoder,
    embedding, vision, and audio modules.
  - Add dataset adapters, collators, and dataset option for
    calibration, training, and evaluation.
  - Add ExecuTorch quantization support for export/prepare, encoding
    initialization, calibration, encoding override, conversion, and QDQ EP save.
  - Add source transforms for checkpoint remapping, dtype override, embedding
    scaling, RoPE layout, RMSNorm offset, and linear-to-conv2d conversion.
  - Expand unit coverage for model preparation, quantization, source transforms,
    datasets, and pipeline stage behavior.
@pytorch-bot

pytorch-bot Bot commented Sep 23, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/23050

Note: Links to docs will display an error until the docs builds have been completed.

❌ 14 Awaiting Approval, 1 New Failure

As of commit 4e19eb9 with merge base 9520b05 (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

NEW FAILURE - The following job has failed:

  • Cadence Build & Test / Resolve CI docker image / resolve (gh)
    ##[error]Refusing to check out fork pull request code from a 'pull_request_target' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access. Fetching and executing a fork's code in that trusted context commonly leads to "pwn request" vulnerabilities. To opt in, review the risks at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' on the actions/checkout step.

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 23, 2026
@DannyYuyang-quic

Copy link
Copy Markdown
Contributor Author

@pytorchbot label "release notes: qualcomm"

@pytorch-bot pytorch-bot Bot added the release notes: qualcomm Changes to the Qualcomm backend delegate label Sep 23, 2026
@DannyYuyang-quic

DannyYuyang-quic commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

Hi @psiddh,

TL;DR:

This PR makes the GenAI Pipeline runnable through backends/qualcomm/genai_pipeline/cli.py for the models supported by the existing llama.py flow. It covers model preparation and basic dataset-backed PTQ calibration, producing quantized QDQ models.

The existing examples/ and legacy llama.py flow remain unchanged.
Advanced features, including QAT and AttentionSink, are intentionally out of scope for GenAI Pipeline and
will be introduced in a follow-up PR.

Together with PR B1, Compilation Foundation (#22846), the following commands
produce quantized QDQ models:

LLM

python -m backends.qualcomm.genai_pipeline.cli --model gemma3-1b --soc SM8750 --calib-samples examples/qualcomm/oss_scripts/llama/assets/samples/text.json --compile-only --max-seq-len 1024

Multimodal LLM

Vision-Language model

python -m backends.qualcomm.genai_pipeline.cli --model internvl3_1b --soc SM8750 --calib-samples examples/qualcomm/oss_scripts/llama/assets/samples/vision.json --compile-only --max-seq-len 1024

Audio-Language model

python -m backends.qualcomm.genai_pipeline.cli  --model granite_speech_3_3-2b --soc SM8750 --calib-samples examples/qualcomm/oss_scripts/llama/assets/samples/audio --compile-only --max-seq-len 1024

Please have a look. Thanks!

cc: @shewu-quic @winskuo-quic @qti-horodnic

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. release notes: qualcomm Changes to the Qualcomm backend delegate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant