Skip to content

Commit 6018283

Browse files
authored
Qualcomm AI Engine Direct - [GenAI Pipeline] PR1: Core Data Model, Engine Routing & Exceptions (#20409)
## Summary This pr introduces the foundational data model for the GenAI pipeline under `backends/qualcomm/genai_pipeline/`. This is the first of 6 PRs total in phase 1, creating the skeleton framework. It covers configuration data classes, pipeline context with builder pattern, engine routing, exception hierarchy, and constants. No existing files are modified. ### What's included #### InputConfig / OutputConfig data classes: - `ModelPreparationInputConfig` / `ModelPreparationOutputConfig` - `QuantizationInputConfig` / `QuantizationOutputConfig` - `CompilationInputConfig` / `CompilationOutputConfig` - `InferenceInputConfig` / `InferenceOutputConfig` Each stage receives an `InputConfig` and produces an `OutputConfig` — no ambiguity about which fields are inputs vs outputs. #### Pipeline context: - `PipelineContext`: immutable frozen data class carrying user inputs (model_name, soc_model, prompt, artifact_dir). - `PipelineContextBuilder`: builder pattern with required-field validation at `build()` time. #### Engine routing: - `EngineProxy`: maps pipeline stages to engine types with construction-time validation. - `EngineType` enum: (EXECUTORCH). #### Exception hierarchy: - `PipelineError`: base exception. - `StageError`: stage execution errors with stage name + original exception chaining. - `ConfigValidationError`: build-time validation errors. - `EngineNotAvailableError`: engine not installed errors. #### Constants & versioning: - `pipeline_types.py`: stage name constants (STAGE_QUANTIZATION, etc.). - `__version__ = "1.0.0"`. #### Unit tests: - Config defaults, field independence, mutable defaults. - Context builder validation (success + all failure paths). - Context immutability. - Engine proxy routing, defaults, validation. - Shared test utilities in `test_utils.py`. ### PR Review Checklist All new classes follow single responsibility (one class per file) - Yes. All dependencies are injected via constructor with sensible defaults - Yes. All external calls are behind injectable interfaces - N/A, no external calls in this PR. Unit tests cover every public method - Yes. No existing files are modified (Phase 1 constraint) - Yes Docstrings on all public classes and methods - Yes. Type annotations on all function signatures - Yes. Logging follows the strategy in the LLD - N/A, no logging in this PR. ### Future PRs - PR 1: Core data model, engine routing & exceptions: this pr. - PR 2: Strategy interfaces & stage wrappers: pending. - PR 3: Pipeline orchestrator: pending. - PR 4: Adapter interfaces & default implementations: pending. - PR 5: Model preparation & quantization strategies: pending - PR 6: Compilation & inference strategy implementations: pending. - PR 7: Integration & E2E tests: pending. ## Test plan ``` python -m pytest \ backends/qualcomm/genai_pipeline/tests/test_pipeline_context.py \ backends/qualcomm/genai_pipeline/tests/test_engine_proxy.py \ backends/qualcomm/genai_pipeline/tests/test_exceptions.py \ backends/qualcomm/genai_pipeline/tests/configs/ \ -v ``` ### Test Coverage Command to run: ``` python -m pytest \ backends/qualcomm/genai_pipeline/tests/test_pipeline_context.py \ backends/qualcomm/genai_pipeline/tests/test_engine_proxy.py \ backends/qualcomm/genai_pipeline/tests/test_exceptions.py \ backends/qualcomm/genai_pipeline/tests/configs/ \ --cov=backends/qualcomm/genai_pipeline \ --cov-config=backends/qualcomm/.coveragerc \ --cov-report=term-missing \ -v ``` Result: ``` Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------------------------------------------------------------------- backends/qualcomm/genai_pipeline/configs/compilation_input_config.py 11 0 0 0 100% backends/qualcomm/genai_pipeline/configs/compilation_output_config.py 8 0 0 0 100% backends/qualcomm/genai_pipeline/configs/inference_input_config.py 12 0 0 0 100% backends/qualcomm/genai_pipeline/configs/inference_output_config.py 9 0 0 0 100% backends/qualcomm/genai_pipeline/configs/model_preparation_input_config.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/configs/model_preparation_output_config.py 11 0 0 0 100% backends/qualcomm/genai_pipeline/configs/quantization_input_config.py 11 0 0 0 100% backends/qualcomm/genai_pipeline/configs/quantization_output_config.py 5 0 0 0 100% backends/qualcomm/genai_pipeline/engine_proxy.py 20 0 4 0 100% backends/qualcomm/genai_pipeline/exceptions.py 18 0 4 0 100% backends/qualcomm/genai_pipeline/pipeline_context.py 47 0 10 0 100% ------------------------------------------------------------------------------------------------------------------------- TOTAL 159 0 18 0 100% ```
1 parent 69eb495 commit 6018283

23 files changed

Lines changed: 1055 additions & 0 deletions

backends/qualcomm/.coveragerc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[run]
2+
branch = True
3+
source = backends/qualcomm/genai_pipeline
4+
5+
omit =
6+
*/__init__.py
7+
*/tests/*
8+
*/__pycache__/*
9+
pipeline_types.py
10+
11+
[report]
12+
show_missing = True
13+
14+
omit =
15+
*/__init__.py
16+
*/tests/*
17+
*/__pycache__/*
18+
pipeline_types.py
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
__version__ = "1.0.0"
8+
9+
from executorch.backends.qualcomm.genai_pipeline.configs import (
10+
CompilationInputConfig,
11+
CompilationOutputConfig,
12+
InferenceInputConfig,
13+
InferenceOutputConfig,
14+
ModelPreparationInputConfig,
15+
ModelPreparationOutputConfig,
16+
QuantizationInputConfig,
17+
QuantizationOutputConfig,
18+
)
19+
from executorch.backends.qualcomm.genai_pipeline.engine_proxy import EngineProxy
20+
from executorch.backends.qualcomm.genai_pipeline.exceptions import (
21+
ConfigValidationError,
22+
EngineNotAvailableError,
23+
PipelineError,
24+
StageError,
25+
)
26+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import (
27+
PipelineContext,
28+
PipelineContextBuilder,
29+
)
30+
from executorch.backends.qualcomm.genai_pipeline.pipeline_types import EngineType
31+
32+
__all__ = [
33+
"CompilationInputConfig",
34+
"CompilationOutputConfig",
35+
"ConfigValidationError",
36+
"EngineNotAvailableError",
37+
"EngineProxy",
38+
"EngineType",
39+
"InferenceInputConfig",
40+
"InferenceOutputConfig",
41+
"ModelPreparationInputConfig",
42+
"ModelPreparationOutputConfig",
43+
"PipelineContext",
44+
"PipelineContextBuilder",
45+
"PipelineError",
46+
"QuantizationInputConfig",
47+
"QuantizationOutputConfig",
48+
"StageError",
49+
]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_input_config import (
8+
CompilationInputConfig,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_output_config import (
11+
CompilationOutputConfig,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.configs.inference_input_config import (
14+
InferenceInputConfig,
15+
)
16+
from executorch.backends.qualcomm.genai_pipeline.configs.inference_output_config import (
17+
InferenceOutputConfig,
18+
)
19+
from executorch.backends.qualcomm.genai_pipeline.configs.model_preparation_input_config import (
20+
ModelPreparationInputConfig,
21+
)
22+
from executorch.backends.qualcomm.genai_pipeline.configs.model_preparation_output_config import (
23+
ModelPreparationOutputConfig,
24+
)
25+
from executorch.backends.qualcomm.genai_pipeline.configs.quantization_input_config import (
26+
QuantizationInputConfig,
27+
)
28+
from executorch.backends.qualcomm.genai_pipeline.configs.quantization_output_config import (
29+
QuantizationOutputConfig,
30+
)
31+
32+
__all__ = [
33+
"CompilationInputConfig",
34+
"CompilationOutputConfig",
35+
"InferenceInputConfig",
36+
"InferenceOutputConfig",
37+
"ModelPreparationInputConfig",
38+
"ModelPreparationOutputConfig",
39+
"QuantizationInputConfig",
40+
"QuantizationOutputConfig",
41+
]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass, field
10+
from pathlib import Path
11+
from typing import List, Optional, TYPE_CHECKING
12+
13+
if TYPE_CHECKING:
14+
from executorch.backends.qualcomm.serialization.qc_schema import (
15+
QcomChipset,
16+
QnnExecuTorchBackendType,
17+
)
18+
from executorch.exir.backend.compile_spec import CompileSpec
19+
from torch import nn
20+
21+
22+
@dataclass
23+
class CompilationInputConfig:
24+
"""Input configuration for the compilation stage.
25+
26+
Attributes:
27+
soc_model: The target SoC (e.g., QcomChipset.SM8750). Required.
28+
backend_type: QNN backend type (HTP, GPU, LPAI, etc.). Required.
29+
model: The nn.Module to compile (quantized or original for FP16 mode).
30+
artifact_dir: Directory to store compiled artifacts.
31+
compile_specs: QNN compiler specifications for backend delegation.
32+
"""
33+
34+
soc_model: "QcomChipset"
35+
backend_type: "QnnExecuTorchBackendType"
36+
model: Optional["nn.Module"] = None
37+
artifact_dir: Path = field(default_factory=lambda: Path("."))
38+
compile_specs: Optional[List["CompileSpec"]] = None
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass
10+
from pathlib import Path
11+
from typing import List, Optional, TYPE_CHECKING
12+
13+
if TYPE_CHECKING:
14+
from executorch.devtools.etrecord import ETRecord
15+
16+
17+
@dataclass
18+
class CompilationOutputConfig:
19+
"""Output produced by the compilation stage.
20+
21+
Attributes:
22+
artifact_paths: Paths to the compiled artifacts (.pte files).
23+
List to support multi-split models where compilation produces
24+
multiple .pte files (e.g., prefill + decode).
25+
etrecord: Optional ETRecord for debugging. ExecuTorch engine only.
26+
"""
27+
28+
artifact_paths: Optional[List[Path]] = None
29+
etrecord: Optional["ETRecord"] = None
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass, field
10+
from pathlib import Path
11+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
12+
13+
if TYPE_CHECKING:
14+
from executorch.backends.qualcomm.serialization.qc_schema import QcomChipset
15+
16+
17+
@dataclass
18+
class InferenceInputConfig:
19+
"""Input configuration for the inference stage.
20+
21+
Attributes:
22+
soc_model: The target SoC (e.g., QcomChipset.SM8750). Required.
23+
artifact_paths: Paths to compiled model artifacts (.pte files).
24+
List to support multi-split models (e.g., prefill + decode).
25+
tokenizer: The tokenizer instance for encoding/decoding.
26+
runtime_tokenizer_path: Path to runtime tokenizer for on-device use.
27+
prompt: The user prompt(s) for text generation.
28+
inference_options: Engine-specific inference options.
29+
"""
30+
31+
soc_model: "QcomChipset"
32+
artifact_paths: Optional[List[Path]] = None
33+
tokenizer: Any = None
34+
runtime_tokenizer_path: Optional[Path] = None
35+
prompt: Optional[List[str]] = None
36+
inference_options: Dict[str, Any] = field(default_factory=dict)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass, field
10+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
11+
12+
if TYPE_CHECKING:
13+
from executorch.devtools.etdump.schema_flatcc import ETDump
14+
15+
16+
@dataclass
17+
class InferenceOutputConfig:
18+
"""Output produced by the inference stage.
19+
20+
Attributes:
21+
inference_results: Generated text output(s) from the model.
22+
performance_metrics: Performance data (e.g., TTFT, tokens/sec).
23+
eval_results: Evaluation metric results (e.g., SQNR, perplexity).
24+
etdump: Optional ETDump for debugging. ExecuTorch engine only.
25+
"""
26+
27+
inference_results: Optional[List[str]] = None
28+
performance_metrics: Dict[str, Any] = field(default_factory=dict)
29+
eval_results: Dict[str, Any] = field(default_factory=dict)
30+
etdump: Optional["ETDump"] = None
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from dataclasses import dataclass, field
8+
from typing import Any, Dict
9+
10+
11+
@dataclass
12+
class ModelPreparationInputConfig:
13+
"""Input configuration for the model preparation stage.
14+
15+
Attributes:
16+
model_name: Model identifier (e.g., "llama3_2-1b_instruct"). Required.
17+
soc_model: Target SoC (e.g., "SM8750"). Required.
18+
extra_options: Additional model-preparation-specific options.
19+
"""
20+
21+
model_name: str
22+
soc_model: str
23+
extra_options: Dict[str, Any] = field(default_factory=dict)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass
10+
from pathlib import Path
11+
from typing import Any, List, Optional, TYPE_CHECKING
12+
13+
if TYPE_CHECKING:
14+
from torch import nn
15+
16+
17+
@dataclass
18+
class ModelPreparationOutputConfig:
19+
"""Output produced by the model preparation stage.
20+
21+
Attributes:
22+
model_module: The prepared nn.Module ready for quantization.
23+
tokenizer: The tokenizer instance for encoding/decoding text.
24+
calibration_data: Dataset samples for calibration during quantization.
25+
runtime_tokenizer_path: Path to runtime tokenizer for on-device inference.
26+
chat_template: Optional chat template for instruct models.
27+
"""
28+
29+
model_module: Optional["nn.Module"] = None
30+
tokenizer: Any = None
31+
calibration_data: Optional[List[Any]] = None
32+
runtime_tokenizer_path: Optional[Path] = None
33+
chat_template: Optional[str] = None
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from __future__ import annotations
8+
9+
from dataclasses import dataclass, field
10+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
11+
12+
if TYPE_CHECKING:
13+
from executorch.backends.qualcomm.serialization.qc_schema import (
14+
QcomChipset,
15+
QnnExecuTorchBackendType,
16+
)
17+
from torch import nn
18+
19+
20+
@dataclass
21+
class QuantizationInputConfig:
22+
"""Input configuration for the quantization stage.
23+
24+
Attributes:
25+
soc_model: The target SoC (e.g., QcomChipset.SM8750). Required.
26+
backend_type: QNN backend type (HTP, GPU, LPAI, etc.). Required.
27+
model_module: The nn.Module to quantize.
28+
calibration_data: Calibration dataset samples.
29+
quant_recipe: Quantization recipe (per-layer bit widths, group sizes, etc.).
30+
extra_options: Additional quantization-specific options.
31+
"""
32+
33+
soc_model: "QcomChipset"
34+
backend_type: "QnnExecuTorchBackendType"
35+
model_module: Optional["nn.Module"] = None
36+
calibration_data: Optional[List[Any]] = None
37+
quant_recipe: Any = None
38+
extra_options: Dict[str, Any] = field(default_factory=dict)

0 commit comments

Comments
 (0)