{ "model": "whisper-base", "precision": "fp32dec-lmq8", "upstream": { "model": "openai/whisper-base", "revision": "e37978b90ca9030d5170a5c07aadb050351a65bb", "official": true, "license": "apache-2.0 (model card)", "files_sha256": { "model.safetensors": "07cadb9f25677c8d50df603e66a98fbd842cce45047139baeb16e6219a1e807b", "config.json": "a153c53883a6799b6f056b4a8d1a515c9926d03994682ba88a7616618d7da0c1", "generation_config.json": "444b3f636d2fff89dd9ecf549e2a085b61f7ff0fa0246d4628bac6a3b8cc9ba4", "preprocessor_config.json": "9b5cd03a36fbb8a627c64d98a5b5b126ead95a77720723944487311f0110b666", "vocab.json": "8f680bba319e01a653d2e8a5dbc17a9157179e0576e6ce74ce0c06356c6e24f9", "tokenizer.json": "27fc476bfe7f17299480be2273fc0608e4d5a99aba2ab5dec5374b4482d1a566", "tokenizer_config.json": "2a4c4281cf9f51ac6ccc406fdc711a087afe6530f671fa7b80953edc498275ce", "merges.txt": "2df2990a395e35e8dfbc7511e08c12d56018d8d04691e0133e5d63b21e154dc6", "normalizer.json": "bf1c507dc8724ca9cf9903640dacfb69dae2f00edee4f21ceba106a7392f26dd", "added_tokens.json": "9715fd2243b6f06a5858b5e32950d2853f73dd5bc201aafcf76f5082a2d8acd1", "special_tokens_map.json": "e67ae3a0aaa99abcd9f187138e12db1f65c16a14761c50ef10eef2c174a7a691" }, "loader": "transformers.WhisperForConditionalGeneration.from_pretrained(dtype=float32, attn_implementation='eager')" }, "versions": { "python": "3.12.15+meta", "torch": "2.14.1+cpu", "torchao": "0.18.0+cpu", "executorch": "1.5.1+cpu", "executorch_git": "3b60683923245cf472b7323426920e15623ba361", "transformers": "5.19.0", "huggingface_hub": "2.2.0" }, "export": { "api": "torch.export.export(strict=False) -> to_edge_transform_and_lower(partitioner=[WebGPUPartitioner()]) -> to_executorch()", "partitioner": "executorch.backends.webgpu.partitioner.WebGPUPartitioner() (default compile options; wraps VulkanPartitioner; delegate id VulkanBackend)", "model_code": "recipes/_whisper.py wrappers around the transformers modules (weights shared, forward re-expressed): MelProgram, EncoderProgram, CrossKVProgram, DecoderSplitProgram, DecodeStreamProgram, LMHeadProgram", "quantization": { "decoder_side_linears": { "programs": [ "cross_kv", "decoder_split", "decode_stream" ], "config": "none (fp32)", "lowered_to": "aten.linear (2-D fp32)" }, "lmhead": { "config": "PT2E with executorch.backends.vulkan.quantizer.VulkanQuantizer: weights int8 per-output-channel symmetric (PerChannelMinMaxObserver, the quantizer's own weight spec), input activation int8 per-tensor affine STATIC (HistogramObserver) calibrated on lmhead inputs; lowers to quantized_decomposed.quantize_per_tensor + et_vk.linear_q8ta_q8csw", "lowered_to": "quantized_decomposed.quantize_per_tensor + et_vk.linear_q8ta_q8csw", "calibration_clips": [ "1272-128104-0004", "1272-128104-0009", "1272-128104-0011" ], "calibration_vectors": 157, "input_scale": 1.7133680582046509, "input_zero_point": 84 }, "fp32_programs": [ "mel", "encoder" ], "embedding_table": "int8 rowwise (whisper_embed.i8.bin + whisper_embed.scale.f32.bin)" }, "encoder_attention": "eager", "decoder_attention": "et_vk.sdpa (decoder_split self-attention with a [1,8,64,64] additive causal mask of 0 / -1e30; cross-attention in decoder_split and decode_stream); decode_stream self-attention = llama.update_cache + llama.custom_sdpa, fused by the Vulkan partitioner into sdpa_with_kv_cache + et_vk.select_as_symint", "lmhead_rows": "51872: vocab 51865 padded with zero weights and bias -1000000000.0 (executorch 1.5.1's q4gsw lowering fails for N % 4 != 0; kept for fp32 too so the contract is identical)", "constants": { "max_decoder_rows": 64, "self_attention_cache": [ 1, 448, 8, 64 ], "frames": [ 3000, 400 ], "hop": 160, "prefix_en": [ 50258, 50259, 50359, 50363 ] }, "host_contract": { "frames": "whisper.js buildFrames: zero-pad pcm to 480000 samples, reflect-pad 200 each side, 3000 x 400 windows at hop 160", "log_mel": "between mel and encoder: x = log10(max(p, 1e-10)); x = max(x, max(x) - 8); x = (x + 4) / 4; transpose [1,3000,80] -> [1,80,3000]", "embeddings": "i8[id] * scale[id]; decoder_split: rows 0..p = token embeddings (no positions), zero rows after; decode_stream: token embedding + pos_embed[p]", "argmax": "over logits[..., :51865] (rows 51865..51871 are -1000000000.0)", "cross_kv": "computed once per 30 s window, then passed as 12 inputs to every decoder call" }, "io": { "mel": { "forward": { "inputs": [ { "shape": [ 1, 3000, 400 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 3000, 80 ], "dtype": "float" } ] } }, "encoder": { "forward": { "inputs": [ { "shape": [ 1, 80, 3000 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 1500, 512 ], "dtype": "float" } ] } }, "cross_kv": { "forward": { "inputs": [ { "shape": [ 1, 1500, 512 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" } ] } }, "decoder_split": { "forward": { "inputs": [ { "shape": [ 1, 64, 512 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 64, 512 ], "dtype": "float" } ] } }, "decode_stream": { "forward": { "inputs": [ { "shape": [ 1, 1, 512 ], "dtype": "float" }, { "shape": [ 1 ], "dtype": "long" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" }, { "shape": [ 1, 8, 1500, 64 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 1, 512 ], "dtype": "float" } ] } }, "lmhead": { "forward": { "inputs": [ { "shape": [ 1, 1, 512 ], "dtype": "float" } ], "outputs": [ { "shape": [ 1, 1, 51872 ], "dtype": "float" } ] } } } }, "files": { "whisper_mel.pte": { "bytes": 710976, "sha256": "7cae31829487958454c5a14aecfed0845f6320dd480c24883861fa39b07de497" }, "whisper_encoder.pte": { "bytes": 82420996, "sha256": "841e7702ba8fa73594f0b4e1400230d6b686af958628ead6b22919e9a3e27c69" }, "whisper_cross_kv.pte": { "bytes": 12610560, "sha256": "6e8078924168c21a863ff662e9ccba55ed86bb3826dabd28fea77010e3151012" }, "whisper_decoder_split.pte": { "bytes": 88619264, "sha256": "ade1aedc9e5795ac8c224347b88f1b826f5598e68d1df0961695fd843fa0e9b5" }, "whisper_decode_stream.pte": { "bytes": 89270912, "sha256": "bc2f33ad7aa164059e819247365e2e0a75a3f1a2973024e4fdc67a254d7faa8d" }, "whisper_lmhead.pte": { "bytes": 27184000, "sha256": "68577fa240d29923058fd72b94db583f3ff171302ad12834c2b610e04c559f8e" }, "whisper_embed.i8.bin": { "bytes": 26554880, "sha256": "bc7f8d8336ad935eb8b6374036478d92d679eae156a1d4188d5cc016b5f2dda2" }, "whisper_embed.scale.f32.bin": { "bytes": 207460, "sha256": "1f58851911611b9686851c586365df2fcaaa0727957c05bd163d7c3ccc231f4d" }, "whisper_pos_embed.f32.bin": { "bytes": 917504, "sha256": "88fa1cdbf2b06f86b0ecb7be0fccfc39e906502986572b8cf5319c250e857169" }, "vocab.json": { "bytes": 835550, "sha256": "8f680bba319e01a653d2e8a5dbc17a9157179e0576e6ce74ce0c06356c6e24f9" } }, "graph": { "mel": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "aten.squeeze_copy.dims": 1, "aten.linear.default": 3, "aten.mul.Tensor": 2, "aten.add.Tensor": 1, "aten.view_copy.default": 1 }, "inputs": 1, "outputs": 1 } ] }, "encoder": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "et_vk.prepack.default": 7, "aten.convolution.default": 2, "aten.gelu.default": 8, "aten.clone.default": 1, "aten.permute_copy.default": 31, "aten.squeeze_copy.dims": 25, "aten.add.Tensor": 13, "aten.native_layer_norm.default": 13, "aten.linear.default": 36, "aten.view_copy.default": 37, "aten.mul.Tensor": 6, "aten.bmm.default": 12, "aten._softmax.default": 6 }, "inputs": 1, "outputs": 1 } ] }, "cross_kv": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "aten.squeeze_copy.dims": 12, "aten.linear.default": 12, "aten.view_copy.default": 12, "aten.permute_copy.default": 12 }, "inputs": 1, "outputs": 12 } ] }, "decoder_split": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "et_vk.prepack.default": 2, "aten.add.Tensor": 19, "aten.native_layer_norm.default": 19, "aten.squeeze_copy.dims": 30, "aten.linear.default": 48, "aten.view_copy.default": 60, "aten.permute_copy.default": 36, "et_vk.sdpa.default": 12, "aten.gelu.default": 6 }, "inputs": 13, "outputs": 1 } ] }, "decode_stream": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "et_vk.select_as_symint.default": 1, "aten.native_layer_norm.default": 19, "aten.squeeze_copy.dims": 30, "aten.linear.default": 48, "aten.view_copy.default": 42, "sdpa_with_kv_cache.default": 6, "aten.unsqueeze_copy.default": 18, "aten.add.Tensor": 18, "aten.permute_copy.default": 12, "et_vk.sdpa.default": 6, "aten.gelu.default": 6 }, "inputs": 14, "outputs": 1 } ] }, "lmhead": { "non_delegated_kernels": {}, "delegates": [ { "id": "VulkanBackend", "ops": { "quantized_decomposed.quantize_per_tensor.default": 1, "aten.clone.default": 1, "et_vk.linear_q8ta_q8csw.default": 1 }, "inputs": 1, "outputs": 1 } ] } }, "webgpu_runtime_checks": { "op_list": "checked against --runtime-ops", "mel": { "problems": [], "ok": true, "notes": { "value_kinds": [ "FLOAT32", "Int", "IntList", "Null" ], "aten.linear input ranks": [ "2" ] } }, "encoder": { "problems": [], "ok": true, "notes": { "value_kinds": [ "Bool", "Double", "FLOAT32", "Int", "IntList", "Null", "String", "ValueList" ], "aten.convolution input/weight": [ "((1, 512, 3000), (512, 512, 3))", "((1, 80, 3000), (512, 80, 3))" ], "aten.linear input ranks": [ "2" ] } }, "cross_kv": { "problems": [], "ok": true, "notes": { "value_kinds": [ "FLOAT32", "IntList", "Null" ], "aten.linear input ranks": [ "2" ] } }, "decoder_split": { "problems": [], "ok": true, "notes": { "value_kinds": [ "Double", "FLOAT32", "Int", "IntList", "Null", "String", "ValueList" ], "aten.linear input ranks": [ "2" ], "et_vk.sdpa q/k/mask": [ "((1, 8, 64, 64), (1, 8, 1500, 64), None)", "((1, 8, 64, 64), (1, 8, 64, 64), (1, 8, 64, 64))" ] } }, "decode_stream": { "problems": [], "ok": true, "notes": { "value_kinds": [ "Bool", "Double", "FLOAT32", "INT32", "Int", "IntList", "Null", "String", "SymInt", "ValueList" ], "aten.linear input ranks": [ "2" ], "sdpa_with_kv_cache q/k_cache": [ "((1, 1, 8, 64), (1, 448, 8, 64), 'SymInt')" ], "et_vk.sdpa q/k/mask": [ "((1, 8, 1, 64), (1, 8, 1500, 64), None)" ] } }, "lmhead": { "problems": [], "ok": true, "notes": { "value_kinds": [ "Double", "FLOAT32", "INT32", "INT8", "Int", "Null" ] } } }, "command": "python recipes/whisper-base.py --out out/whisper-base/fp32dec-lmq8 --precision fp32dec-lmq8" }