A03HCY commited on
Commit
c539d8f
·
verified ·
1 Parent(s): 32cf15e

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +184 -1
README.md CHANGED
@@ -1,3 +1,186 @@
1
  ---
2
- license: mit
 
 
 
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ language:
3
+ - en
4
+ - multilingual
5
+ license: apache-2.0
6
+ library_name: codon
7
+ pipeline_tag: feature-extraction
8
+ tags:
9
+ - audio
10
+ - speech
11
+ - whisper
12
+ - encoder
13
+ - feature-extraction
14
+ - safetensors
15
  ---
16
+
17
+ # Whisper-Tiny Audio Encoder (codon format)
18
+
19
+ Encoder-only weights of [openai/whisper-tiny](https://huggingface.co/openai/whisper-tiny),
20
+ re-keyed into the naming convention used by the
21
+ [codon](https://github.com/CodonProject/codon-model) library so they can be loaded into
22
+ `codon.block.model.WhisperTinyAudioEncoder` with a single call.
23
+
24
+ This is a **feature extractor**, not a speech-to-text model: the decoder and the
25
+ tokenizer are intentionally **not** included, so it cannot transcribe audio on its own.
26
+
27
+ ## Files
28
+
29
+ | File | Size | Tensors | Description |
30
+ |---|---|---|---|
31
+ | `whisper_tiny_encoder.safetensors` | 15.7 MB | 67 | Encoder weights, **fp16**, codon key convention |
32
+
33
+ ## Model details
34
+
35
+ | | |
36
+ |---|---|
37
+ | Architecture | Whisper encoder (pre-LN Transformer, bidirectional self-attention) |
38
+ | Parameters | 8,208,384 (8.21M) |
39
+ | `d_model` | 384 |
40
+ | Encoder layers | 4 |
41
+ | Attention heads | 6 (head dim 64) |
42
+ | FFN dim | 1536, GELU |
43
+ | Mel bins | 80 |
44
+ | Max positions | 1500 |
45
+ | Output | `[B, T/2, 384]` for input mel `[B, 80, T]` |
46
+ | Precision | fp16 (upcast to fp32 on load for fp32 execution) |
47
+ | License | Apache-2.0 |
48
+
49
+ ## Requirements
50
+
51
+ ```bash
52
+ pip install codon-model==0.0.7b8
53
+ ```
54
+
55
+ Source: [CodonProject/codon-model](https://github.com/CodonProject/codon-model)
56
+
57
+ ## Usage
58
+
59
+ ```python
60
+ import torch
61
+ from codon.block.model import WhisperTinyAudioEncoder
62
+
63
+ encoder = WhisperTinyAudioEncoder(pool_stride=1)
64
+ encoder.load('whisper_tiny_encoder.safetensors', strict=True)
65
+ encoder = encoder.float() # weights are fp16; upcast for fp32 execution
66
+ encoder.eval()
67
+
68
+ mel = torch.randn(1, 80, 3000) # 30 s of log-mel @ 100 Hz
69
+ with torch.no_grad():
70
+ hidden, _ = encoder(mel)
71
+ print(hidden.shape) # torch.Size([1, 1500, 384])
72
+ ```
73
+
74
+ Half-precision execution is also supported — just call `.half()` and feed a
75
+ half-precision mel instead (expect a larger numerical drift, ~6e-2, since the
76
+ arithmetic itself runs in fp16):
77
+
78
+ Loading straight from this repository:
79
+
80
+ ```python
81
+ encoder = WhisperTinyAudioEncoder().from_remote()
82
+ ```
83
+
84
+ ### Downsampling for LLM consumption
85
+
86
+ The raw encoder emits one token per 20 ms (50 tokens/s), which is usually far too
87
+ dense for a language model. `pool_stride` appends a non-overlapping average pool
88
+ after the encoder (weights are unaffected):
89
+
90
+ ```python
91
+ encoder = WhisperTinyAudioEncoder(pool_stride=8)
92
+ encoder = encoder.float()
93
+ with torch.no_grad():
94
+ hidden, _ = encoder(torch.randn(1, 80, 3000))
95
+ print(hidden.shape) # torch.Size([1, 187, 384]) -> 6.25 tokens/s
96
+ ```
97
+
98
+ ## Tensor naming
99
+
100
+ Keys follow the codon convention (`proj_*` for projections). The full layout:
101
+
102
+ ```
103
+ conv1.weight (384, 80, 3)
104
+ conv1.bias (384,)
105
+ conv2.weight (384, 384, 3)
106
+ conv2.bias (384,)
107
+ embed_positions.weight (1500, 384)
108
+ layers.{0..3}.attn_norm.weight (384,)
109
+ layers.{0..3}.attn_norm.bias (384,)
110
+ layers.{0..3}.attn.proj_q.weight (384, 384)
111
+ layers.{0..3}.attn.proj_q.bias (384,)
112
+ layers.{0..3}.attn.proj_k.weight (384, 384) # no bias
113
+ layers.{0..3}.attn.proj_v.weight (384, 384)
114
+ layers.{0..3}.attn.proj_v.bias (384,)
115
+ layers.{0..3}.attn.proj_o.weight (384, 384)
116
+ layers.{0..3}.attn.proj_o.bias (384,)
117
+ layers.{0..3}.fn_norm.weight (384,)
118
+ layers.{0..3}.fn_norm.bias (384,)
119
+ layers.{0..3}.mlp.proj_fc1.weight (1536, 384)
120
+ layers.{0..3}.mlp.proj_fc1.bias (1536,)
121
+ layers.{0..3}.mlp.proj_fc2.weight (384, 1536)
122
+ layers.{0..3}.mlp.proj_fc2.bias (384,)
123
+ norm.weight (384,)
124
+ norm.bias (384,)
125
+ ```
126
+
127
+ Note that `proj_k` has **no bias** — this mirrors the original Whisper design
128
+ (its `k_proj` is the only projection without a bias in both the encoder and the
129
+ decoder). The positional table uses Whisper's own layout: `weight[:, :192]` holds
130
+ sine values and `weight[:, 192:]` holds cosine values for
131
+ `inv_freq = exp(-log(10000) * arange(192) / 192)`.
132
+
133
+ ## Provenance and verification
134
+
135
+ Weights are copied from `openai/whisper-tiny` (`model.encoder.*`), renamed, and
136
+ saved as fp16. No values were modified: converting the fp32 export to fp16 and back
137
+ to fp32 is bit-exact element-wise, i.e. the source values already only carried fp16
138
+ precision (max absolute weight magnitude is ~16, well inside fp16 range).
139
+
140
+ The codon implementation was verified against the official `transformers`
141
+ implementation (`WhisperModel(...).encoder`) with both models loading the same
142
+ checkpoint (upcast to fp32) and consuming the same input:
143
+
144
+ | mel length | output shape | max abs difference |
145
+ |---|---|---|
146
+ | 3000 | `[2, 1500, 384]` | 5.9e-05 |
147
+ | 1000 (padded) | `[2, 500, 384]` | 3.9e-05 |
148
+ | 512 (padded) | `[2, 256, 384]` | 2.2e-05 |
149
+
150
+ Differences are at fp32 rounding level, not implementation differences.
151
+
152
+ ## Limitations
153
+
154
+ - **Encoder only.** No decoder, no vocabulary, no tokenizer — cannot produce text.
155
+ - **Fixed 30 s input.** Whisper pads every input to 3000 mel frames. Short clips
156
+ must be zero-padded to 3000 and the padded output frames discarded; the padded
157
+ region does influence the valid region through convolution and LayerNorm, so it
158
+ is not equivalent to running the encoder on a shorter input.
159
+ - **Not causal / not streaming.** The encoder is bidirectional and stateless, so it
160
+ cannot be used for incremental streaming without recomputing a full window.
161
+ - **Precision.** Tensors are stored as fp16. The fp32 -> fp16 -> fp32 round trip is
162
+ element-wise exact, so no information was lost relative to the source export, and
163
+ running the model in fp32 after upcasting reproduces the fp32 reference exactly.
164
+ Native fp16 execution (`model.half()`) is supported but introduces the usual
165
+ half-precision drift (~6e-2 on this model).
166
+
167
+ ## Citation
168
+
169
+ If you use these weights, please cite the original work:
170
+
171
+ ```bibtex
172
+ @misc{radford2022whisper,
173
+ doi = {10.48550/ARXIV.2212.04356},
174
+ url = {https://arxiv.org/abs/2212.04356},
175
+ author = {Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman, Greg and McLeavey, Christine and Sutskever, Ilya},
176
+ title = {Robust Speech Recognition via Large-Scale Weak Supervision},
177
+ publisher = {arXiv},
178
+ year = {2022},
179
+ copyright = {arXiv.org perpetual, non-exclusive license}
180
+ }
181
+ ```
182
+
183
+ ## Acknowledgements
184
+
185
+ Original model by OpenAI. This repository only re-keys the encoder weights for use
186
+ with [codon](https://github.com/CodonProject/codon-model).