|
| 1 | +--- |
| 2 | +title: Create LiteRT models |
| 3 | +weight: 3 |
| 4 | + |
| 5 | +### FIXED, DO NOT MODIFY |
| 6 | +layout: learningpathall |
| 7 | +--- |
| 8 | + |
| 9 | +### KleidiAI SME2 support in LiteRT |
| 10 | + |
| 11 | +Only a subset of KleidiAI SME, SME2 micro-kernels has been integrated into XNNPACK. |
| 12 | +These micro-kernels support operators using the following data types and quantization configurations in the LiteRT model. 以下列出的每个operator,kleidiai都会有对应的micro-kernels |
| 13 | +Other operators are using XNNPACK’s default implementation during the inference. |
| 14 | + |
| 15 | +* Fully connected |
| 16 | +| Activations | Weights | Output | |
| 17 | +| ---------------------------- | --------------------------------------- | ---------------------------- | |
| 18 | +| FP32 | FP32 | FP32 | |
| 19 | +| FP32 | FP16 | FP32 | |
| 20 | +| FP32 | Per-channel symmetric INT8 quantization | FP32 | |
| 21 | +| Asymmetric INT8 quantization | Per-channel symmetric INT8 quantization | Asymmetric INT8 quantization | |
| 22 | +| FP32 | Per-channel symmetric INT4 quantization | FP32 | |
| 23 | + |
| 24 | +* Batch Matrix Multiply |
| 25 | +| Input A | Input B | |
| 26 | +| ------- | --------------------------------------- | |
| 27 | +| FP32 | FP32 | |
| 28 | +| FP16 | FP16 | |
| 29 | +| FP32 | Per-channel symmetric INT8 quantization | |
| 30 | + |
| 31 | + |
| 32 | +* Conv2D |
| 33 | +| Activations | Weights | Output | |
| 34 | +| ---------------------------- | ----------------------------------------------------- | ---------------------------- | |
| 35 | +| FP32 | FP32, pointwise (kernerl size is 1) | FP32 | |
| 36 | +| FP32 | FP16, pointwise (kernerl size is 1) | FP32 | |
| 37 | +| FP32 | Per-channel or per-tensor symmetric INT8 quantization | FP32 | |
| 38 | +| Asymmetric INT8 quantization | Per-channel or per-tensor symmetric INT8 quantization | Asymmetric INT8 quantization | |
| 39 | + |
| 40 | + |
| 41 | +* TransposeConv |
| 42 | +| Activations | Weights | Output | |
| 43 | +| ---------------------------- | ----------------------------------------------------- | ---------------------------- | |
| 44 | +| Asymmetric INT8 quantization | Per-channel or per-tensor symmetric INT8 quantization | Asymmetric INT8 quantization | |
| 45 | + |
| 46 | + |
| 47 | +### Create LiteRT models by Keras |
| 48 | + |
| 49 | +To evaluate the performance of SME2 acceleration per operator, the following script is provided as an example. It uses the Keras to create a simple model containing only a single fully connected operator and convert it into the LiteRT model. |
| 50 | + |
| 51 | +``` python |
| 52 | +import tensorflow as tf |
| 53 | +import numpy as np |
| 54 | +import os |
| 55 | + |
| 56 | +batch_size = 100 |
| 57 | +input_size = 640 |
| 58 | +output_size = 1280 |
| 59 | + |
| 60 | +def save_litert_model(model_bytes, filename): |
| 61 | + if os.path.exists(filename): |
| 62 | + print(f"Warning: {filename} already exists and will be overwritten.") |
| 63 | + with open(filename, "wb") as f: |
| 64 | + f.write(model_bytes) |
| 65 | + |
| 66 | +model = tf.keras.Sequential([ |
| 67 | + tf.keras.layers.InputLayer(input_shape=(input_size,), batch_size=batch_size), |
| 68 | + tf.keras.layers.Dense(output_size) |
| 69 | +]) |
| 70 | + |
| 71 | +# Convert to FP32 model |
| 72 | +converter = tf.lite.TFLiteConverter.from_keras_model(model) |
| 73 | +fc_fp32 = converter.convert() |
| 74 | +save_litert_model(fc_fp32, "fc_fp32.tflite") |
| 75 | +``` |
| 76 | + |
| 77 | +The model above is created in FP32 format. As mentioned in the previous section, this operator can invoke the KleidiAI SME2 micro-kernel for acceleration. |
| 78 | + |
| 79 | +You can also optimize this Keras model using post-training quantization to create a LiteRT model that suits your requirements. |
| 80 | + |
| 81 | +* Post-training FP16 quantization |
| 82 | +``` python |
| 83 | +# Convert to model with FP16 weights and FP32 activations |
| 84 | +converter = tf.lite.TFLiteConverter.from_keras_model(model) |
| 85 | +converter.optimizations = [tf.lite.Optimize.DEFAULT] |
| 86 | +converter.target_spec.supported_types = [tf.float16] |
| 87 | +converter.target_spec._experimental_supported_accumulation_type = tf.dtypes.float16 |
| 88 | +fc_fp16 = converter.convert() |
| 89 | +save_litert_model(fc_fp16, "fc_fp16.tflite") |
| 90 | +``` |
| 91 | + |
| 92 | +This method applies FP16 quantization to a model with FP32 operators. In practice, this optimization adds metadata to the model to indicate that the model is compatible with FP16 inference. With this hint, at runtime, XNNPACK replaces the FP32 operators with their FP16 equivalents. It also inserts additional operators that convert the model inputs from FP32 to FP16, and convert the model outputs from FP16 back to FP32. |
| 93 | + |
| 94 | +KleidiAI provides FP16 packing micro-kernels for both the activations and weights matrix, as well as FP16 matrix multiplication micro-kernels. |
| 95 | + |
| 96 | +* Post-training INT8 dynamic range quantization |
| 97 | +``` python |
| 98 | +# Convert to Dynamically Quantized INT8 model (INT8 weights, FP32 activations) |
| 99 | +converter = tf.lite.TFLiteConverter.from_keras_model(model) |
| 100 | +converter.optimizations = [tf.lite.Optimize.DEFAULT] |
| 101 | +fc_int8_dynamic = converter.convert() |
| 102 | +save_litert_model(fc_int8_dynamic, "fc_dynamic_int8.tflite") |
| 103 | +``` |
| 104 | + |
| 105 | +This quantization method optimizes operators with large parameter sizes by quantizing their weights to INT8 while keeping the activations in the FP32 data format. |
| 106 | + |
| 107 | +KleidiAI provides micro-kernels that dynamically quantize activations to INT8 at runtime. KleidiAI also provides packing micro-kernels for the weights matrix, as well as INT8 matrix multiplication micro-kernels that produce FP32 outputs. |
| 108 | + |
| 109 | + |
| 110 | +* Post-training INT8 static quantization |
| 111 | +``` python |
| 112 | +def fake_dataset(): |
| 113 | + for _ in range(100): |
| 114 | + sample = np.random.rand(input_size).astype(np.float32) |
| 115 | + yield [sample] |
| 116 | +# Convert to Statically Quantized INT8 model (INT8 weights and activations) |
| 117 | +converter = tf.lite.TFLiteConverter.from_keras_model(model) |
| 118 | +converter.optimizations = [tf.lite.Optimize.DEFAULT] |
| 119 | +converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] |
| 120 | +converter.target_spec.supported_types = [tf.int8] |
| 121 | +converter.inference_input_type = tf.int8 |
| 122 | +converter.inference_output_type = tf.int8 |
| 123 | +converter.representative_dataset = fake_dataset |
| 124 | +fc_int8_static = converter.convert() |
| 125 | +save_litert_model(fc_int8_static, "fc_static_int8.tflite") |
| 126 | +``` |
| 127 | + |
| 128 | +This quantization method quantizes both the activations and the weights to INT8. |
| 129 | + |
| 130 | +KleidiAI provides INT8 packing micro-kernels for both the activations and weights matrix, as well as INT8 matrix multiplication micro-kernels. |
0 commit comments