Skip to content

Commit 1a46c22

Browse files
YunanAZcopybara-github
authored andcommitted
[LiteRT Torch] End-to-end NPU export pipeline, configuration manager, and master notebook. Upgrade calibration, loader, and quantization to use PreTrainedTokenizerFast and LitertLmBundle.
PiperOrigin-RevId: 958581673
1 parent 02ffd46 commit 1a46c22

17 files changed

Lines changed: 1928 additions & 214 deletions

litert_torch/generative/export_hf/experimental/calib/calibrate.py

Lines changed: 188 additions & 65 deletions
Large diffs are not rendered by default.

litert_torch/generative/export_hf/experimental/calib/loader.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
# ==============================================================================
1515
"""Loader for models."""
1616

17+
import tempfile
1718
from typing import Tuple
1819
from litert_torch.generative.export_hf.experimental.calib import sampling_executor as tfl_sampling_executor
1920
from litert_torch.generative.export_hf.experimental.calib import tokenizer as tokenizer_lib
21+
from litert_torch.generative.export_hf.experimental.litertlm_bundle import litertlm_bundle as litertlm_utils
2022

2123

2224
def _infer_model_specs(
@@ -42,8 +44,8 @@ def _infer_drafter_step(decode_model_path: str):
4244

4345

4446
def load_models(
45-
model_path: str | Tuple[str, str],
46-
embedder_model_path: str,
47+
model_path: str | Tuple[str, str] | None,
48+
embedder_model_path: str | None,
4749
spm_path: str | None,
4850
transformers_model_path: str | None,
4951
max_kv_cache_size: int | None,
@@ -58,8 +60,48 @@ def load_models(
5860
enable_min_max_calibration_update: bool = True,
5961
ema_smoothing_factor: float = 0.95,
6062
use_profiler_based_calibration: bool = False,
63+
input_litertlm: str | None = None,
6164
) -> tfl_sampling_executor.TflSamplingExecutorConfig:
6265
"""Loads the models."""
66+
unpacked = None
67+
if input_litertlm or (
68+
isinstance(model_path, str) and model_path.endswith('.litertlm')
69+
):
70+
bundle_path = input_litertlm or model_path
71+
assert isinstance(bundle_path, str)
72+
unpack_dir = tempfile.mkdtemp(prefix='litertlm_unpacked_')
73+
unpacked = litertlm_utils.unpack_litertlm(bundle_path, unpack_dir)
74+
if (
75+
not model_path
76+
or model_path == (None, None)
77+
or (isinstance(model_path, str) and model_path == bundle_path)
78+
or (
79+
isinstance(model_path, tuple)
80+
and model_path[0] is None
81+
and model_path[1] is None
82+
)
83+
):
84+
model_path = unpacked.get('tf_lite_prefill_decode')
85+
if not embedder_model_path:
86+
embedder_model_path = unpacked.get('tf_lite_embedder')
87+
if not auxiliary_model_path:
88+
auxiliary_model_path = unpacked.get('tf_lite_aux')
89+
if not per_layer_embedder_model_path:
90+
per_layer_embedder_model_path = unpacked.get('tf_lite_per_layer_embedder')
91+
if not spm_path and not transformers_model_path:
92+
spm_path = unpacked.get('SP_Tokenizer')
93+
transformers_model_path = unpacked.get('transformers_model_path')
94+
95+
if not model_path:
96+
raise ValueError(
97+
'Must specify model_path or provide a valid input_litertlm bundle.'
98+
)
99+
if not embedder_model_path:
100+
raise ValueError(
101+
'Must specify embedder_model_path or include embedder in'
102+
' input_litertlm.'
103+
)
104+
63105
if isinstance(model_path, tuple):
64106
prefill_model_path, decode_model_path = model_path
65107
decode_model_path = decode_model_path or prefill_model_path
@@ -158,7 +200,11 @@ def load_models(
158200
)
159201
tokenizer_config = tokenizer_lib.TokenizerConfig(
160202
vocab_path=spm_path,
161-
transformers_model_path=transformers_model_path
203+
transformers_model_path=transformers_model_path if not unpacked else None,
204+
tokenizer_json_path=unpacked.get('tokenizer_json_path')
205+
if unpacked
206+
else None,
207+
chat_template=unpacked.get('chat_template') if unpacked else None,
162208
)
163209
return tfl_sampling_executor.TflSamplingExecutorConfig(
164210
prefill_model_entries=prefill_model_entries,
@@ -181,4 +227,5 @@ def load_models(
181227
enable_min_max_calibration_update=enable_min_max_calibration_update,
182228
ema_smoothing_factor=ema_smoothing_factor,
183229
use_profiler_based_calibration=use_profiler_based_calibration,
230+
stop_tokens=unpacked.get('stop_token_ids') if unpacked else None,
184231
)

litert_torch/generative/export_hf/experimental/calib/quant_utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,25 @@ def get_example_prompt(
107107
tokenizer: tokenizer_lib.Tokenizer | None = None,
108108
) -> str | tokenizer_lib.Request:
109109
"""Gets the prompt from the example."""
110+
if isinstance(example, str):
111+
prompt = example
112+
if enable_formatting:
113+
prompt = PROMPT_TEMPLATE_PREFIX + prompt + PROMPT_TEMPLATE_SUFFIX
114+
return prompt
115+
110116
if isinstance(example, dict):
117+
if 'text' in example and isinstance(example['text'], str):
118+
prompt = example['text']
119+
if enable_formatting:
120+
prompt = PROMPT_TEMPLATE_PREFIX + prompt + PROMPT_TEMPLATE_SUFFIX
121+
return prompt
122+
123+
if 'prompt' in example and isinstance(example['prompt'], str):
124+
prompt = example['prompt']
125+
if enable_formatting:
126+
prompt = PROMPT_TEMPLATE_PREFIX + prompt + PROMPT_TEMPLATE_SUFFIX
127+
return prompt
128+
111129
if 'messages' in example:
112130
user_messages = [
113131
msg for msg in example['messages'] if msg.get('role') == 'user'
@@ -118,6 +136,7 @@ def get_example_prompt(
118136
tokenize=False,
119137
add_generation_prompt=True,
120138
)
139+
assert isinstance(prompt, str)
121140
print(f'\n--- Formatted prompt using chat template:\n{prompt}\n---')
122141
return prompt
123142
else:

0 commit comments

Comments
 (0)