# LoRA LoRA features can be enabled in two ways: via a YAML recipe (recommended) or through programmatic configuration. Both approaches support multi-adapter quantization, per-use-case calibration, and on-device adapter switching. **Validated models:** Qwen3 4B, Llama 3.2 3B. The pipeline LoRA feature enables: - **Multi-adapter support** — declare multiple adapters and group them into named use cases (e.g. “function\_calling”, “summarization”). - **Adapter-aware quantization** — quantize the base model while preserving LoRA-specific updatable weights so adapters can be swapped at runtime without full recompilation. - **Per-use-case calibration** — each use case can specify its own calibration dataset for optimal quantization quality. - **Runtime adapter switching** — select which adapter(s) to activate at generation time via `UseCaseRunConfig`. LoRA adapters are expected as PEFT-format directories containing `adapter_model.safetensors` and `adapter_config.json`. ## Approach 1: YAML Recipe Pre-built LoRA recipes are provided for validated models: - `recipes/llama/meta-llama--Llama-3.2-3B-lora.yaml` - `recipes/qwen3/Qwen--Qwen3-4B-lora.yaml` To use a recipe, replace the placeholder values (``, ``, etc.) with your actual adapter details: from qairt.experimental.pipeline.torch.llm.pipeline import LLMPipeline pipe = LLMPipeline.from_pretrained( "meta-llama/Llama-3.2-3B-Instruct", recipe="path/to/meta-llama--Llama-3.2-3B-lora.yaml", ) pipe.construct() Copy to clipboard Recipe `features.lora` block The `features.lora` section in the YAML recipe defines: features: lora: quant_updatable_mode: adapter_only # adapter_only, all, none adapters: my_adapter: path: /path/to/adapter # dir with adapter_model.safetensors + adapter_config.json use_cases: my_use_case: adapters: [my_adapter] calibration_dataset: xlam # wikitext, xlam, disc calibration_dataset_path: /path/to/xlam # required for xlam, disc lora_scaling: [1.0] # per-adapter alpha multiplier Copy to clipboard **Fields:** - `quant_updatable_mode` - Controls which quantized weights are updatable at runtime: - `adapter_only` (default) — only LoRA A/B matrices are updatable. Smallest runtime footprint, fastest adapter switching. - `all` — all quantized tensors are updatable. Larger memory footprint but allows broader runtime modifications. - `none` — no updatable weights. Adapters are baked into the compiled model; switching requires recompilation. - `adapters` - Dictionary mapping adapter names to their configuration. Each adapter points to a PEFT directory containing `adapter_model.safetensors` and `adapter_config.json`. - `use_cases` - Dictionary of named use cases. Each use case specifies: - `adapters`: list of adapter names (keys from the `adapters` dict) - `calibration_dataset`: dataset used during per-use-case quantization - `calibration_dataset_path`: local path for datasets that require one (e.g., `xlam`, `disc`) - `lora_scaling`: per-adapter alpha multiplier list (length must match `adapters`); `1.0` preserves the adapter’s native scaling (`lora_alpha / r`) ## Approach 2: Programmatic Config Create a `PipelineFeatures` object with a `LoRAFeatureConfig`, then pass it to `LLMPipeline.from_pretrained()`. The pipeline auto-discovers the correct recipe from the model ID. from pathlib import Path from qairt import DevicePlatformType from qairt.api.configs.device import Device from qairt.experimental.pipeline.torch.llm.lora.configs import ( LoRAAdapterConfig, LoRAFeatureConfig, LoRAUseCaseConfig, ) from qairt.experimental.pipeline.torch.llm.pipeline import LLMPipeline, PipelineFeatures from qairt.modules.lora.lora_config import AdapterRunConfig, UseCaseRunConfig # 1. Define adapters and use cases features = PipelineFeatures( lora=LoRAFeatureConfig( adapters={ "function": LoRAAdapterConfig(path=Path("/path/to/function_adapter")), }, use_cases={ "function": LoRAUseCaseConfig( adapters=["function"], calibration_dataset="xlam", calibration_dataset_path="/path/to/xlam", lora_scaling=[1.0], ), }, ) ) # 2. Load the pipeline (recipe auto-discovered from model ID) pipe = LLMPipeline.from_pretrained( "meta-llama/Llama-3.2-3B-Instruct", features=features, enable_cache=True, ) # 3. Construct (load → quantize → build) pipe.construct() # 4. Generate with adapter switching device = Device(type=DevicePlatformType.ANDROID, identifier="") lora_run_config = UseCaseRunConfig( use_case_name="function", adapters=[AdapterRunConfig(adapter_name="function", alpha=1.0)], ) result = pipe.generate("Hello!", device=device, lora_config=lora_run_config) result.print() Copy to clipboard Configuration Reference See the [LoRA API reference](https://docs.qualcomm.com/doc/80-87189-2/topic/qairt-pipeline-lora.html) for full details on `LoRAFeatureConfig`, `LoRAAdapterConfig`, `LoRAUseCaseConfig`, `UseCaseRunConfig`, and `AdapterRunConfig`. UseCaseRunConfig / AdapterRunConfig Runtime configuration for adapter switching at generation time: from qairt.modules.lora.lora_config import AdapterRunConfig, UseCaseRunConfig config = UseCaseRunConfig( use_case_name="function", adapters=[ AdapterRunConfig(adapter_name="function", alpha=1.0), ], ) result = pipe.generate(prompt, device=device, lora_config=config) Copy to clipboard `UseCaseRunConfig` selects which compiled use case to activate. `AdapterRunConfig` specifies the per-adapter alpha at inference time, allowing dynamic scaling without recompilation (when `quant_updatable_mode` is `"adapter_only"` or `"all"`). Validation The `LoRAAdapterConfig.path` field uses Pydantic `DirectoryPath`, which validates that the path exists and is a directory at config parse time. If you load a YAML recipe without replacing the placeholder ``, Pydantic raises a `ValidationError` immediately with a clear message. Additional validation occurs in `load_lora_adapter_metadata()`: 1. **Path existence** — all adapter directories must exist. 2. **LoraConfig loading** — each directory must contain a valid PEFT `adapter_config.json`. 3. **Alpha computation** — per-use-case effective alpha scalings are derived from `lora_alpha / r * lora_scaling`. ## Advanced Flow (Building Blocks) For full control over the quantization process, the pipeline’s building blocks can be used directly without the `Pipeline` orchestrator. **Steps:** 1. **Load base model** — `QcAutoModelForCausalLM.from_pretrained()` with Qc re-authoring. 2. **Apply backend adaptations** — `Adapter.apply_adaptations(model, backend="HTP")`. 3. **Load adapter metadata** — `load_lora_adapter_metadata(lora_cfg)` validates paths, loads PEFT `LoraConfig` objects, and computes effective alpha scalings. 4. **Build calibration dataloader** — any `DataLoader` yielding dicts with `input_ids` tensors of shape `(batch, sequence_length)`. 5. **Quantize base model** — `LPBQ_SeqMSE_Recipe().apply(...)` runs blockwise topology, SeqMSE optimization, and calibration. 6. **Export base model** — ONNX + encodings via `result.export()`. 7. **Export LoRA artifacts** — base torch encodings (`export_base_torch_encodings()`), node mapping (`export_base_node_mapping()`), and metadata YAML (`write_top_level_lora_metadata()`). 8. **Per-use-case LoRA quantization** — for each use case: 1. `attach_lora_adapters()` — remap configs, load weights, prepare for quantization. 2. Build per-use-case calibration dataloader. 3. `quantize_lora_use_case()` — create QuantSim, configure LoRA quantizers, adapt base encodings, calibrate, and export. 9. **Build container** — `GenAIBuilderFactory.create()` with `LoraBuilderInputConfig` pointing to the metadata YAML. 10. **Generate on device** — load container, select use case via `UseCaseRunConfig`, generate. **Key building block functions:** - `load_lora_adapter_metadata()` — 3-pass validation: paths, LoraConfig loading, alpha computation. - `attach_lora_adapters()` — adapter injection with post-MPP name remapping. - `quantize_lora_use_case()` — per-use-case quantize + export loop. - `export_base_torch_encodings()` — locate/copy base encodings for adapter encoding adaptation. - `export_base_node_mapping()` — map PyTorch module names to ONNX op names. - `write_top_level_lora_metadata()` — generate the metadata YAML consumed by `LoraBuilderInputConfig`. Last Published: Aug 26, 2026 [Previous Topic Advanced Features](https://docs.qualcomm.com/bundle/publicresource/80-87189-2/topics/index_advanced_features.md) [Next Topic Advanced Usage](https://docs.qualcomm.com/bundle/publicresource/80-87189-2/topics/pipeline_expert_usage.md)