ONNX
Prince-1 commited on
Commit
8cfba33
Β·
verified Β·
1 Parent(s): 66d25b0

Add files using upload-large-folder tool

Browse files
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ higgs_audio_tokenizer_architecture.png filter=lfs diff=lfs merge=lfs -text
37
+ fp16/semantic_encoder.onnx.data filter=lfs diff=lfs merge=lfs -text
38
+ fp16/acoustic_encoder.onnx.data filter=lfs diff=lfs merge=lfs -text
39
+ fp16/higgs_decoder.onnx.data filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ library_name: onnx
4
+ base_model:
5
+ - bosonai/higgs-audio-v2-tokenizer
6
+ - eustlb/higgs-audio-v2-tokenizer
7
+ ---
8
+
9
+ # Higgs Audio Tokenizer
10
+
11
+ <div align="center" style="display: flex; justify-content: center; margin-top: 10px; flex-wrap: wrap; gap: 8px;">
12
+ <a href="https://boson.ai/blog/higgs-audio-v2"><img src='https://img.shields.io/badge/πŸš€-Launch Blogpost-228B22' style="margin-right: 5px;"></a>
13
+ <a href="https://github.com/boson-ai/higgs-audio"><img src="https://img.shields.io/badge/πŸ’»-Github%20Repo-9C276A" style="margin-right: 5px;"></a>
14
+ </div>
15
+
16
+ Check our open-source repository https://github.com/boson-ai/higgs-audio for more details!
17
+
18
+
19
+ We introduce a new discretized audio tokenizer that runs at just **25 frames per second** while keepingβ€”or even improvingβ€”audio quality compared to tokenizers with twice the bitrate. Our model is the first to train on **24 kHz data** covering speech, music, and sound events in one unified system. It also uses a simple non-diffusion encoder/decoder for fast, batch inference.
20
+
21
+ <p>
22
+ <img src="./higgs_audio_tokenizer_architecture.png" alt="Architecture diagram of the Higgs Audio Tokenizer" width=900>
23
+ </p>
24
+
25
+ ## Usage
26
+
27
+ ### Transformers πŸ€—
28
+
29
+ Higgs Audio V2 Tokenizer is supported natively in `transformers`: [see the doc](https://huggingface.co/docs/transformers/en/model_doc/higgs_audio_v2_tokenizer).
30
+
31
+ ```bash
32
+ uv pip install "transformers>=5.3.0"
33
+ ```
34
+
35
+ ### Onnx
36
+
37
+ The model is divided into 4 submodels :
38
+
39
+ - `account_encoder.onnx`
40
+ - `higgs_decoder.onnx`
41
+ - `quantizer_encoder.onnx`
42
+ - `semantic_encoder.onnx`
43
+
44
+ ```bash
45
+ python higgs_inference.py --input speech.wav --output reconstructed.wav
46
+ ```
47
+
48
+ ## Basics of Audio Quantization
49
+
50
+ An audio signal sampled at \\(f_s\\) Hz is first split into frames by an encoder with hop size \\(M\\), giving a frame rate \\(f_r = \frac{f_s}{M}\quad\text{(frames/s)}.\\)
51
+ Two common quantizers are:
52
+
53
+ - **Residual Vector Quantization (RVQ)**: \\(N_q\\) cascaded vector‑quantizer layers, each with codebook size \\(N_{cb}\\). When \\(N_{q}=1\\), it degenerates to ordinary vector quantization.
54
+ - **Finite Scalar Quantization (FSQ)**: A single-layer scalar quantizer in which
55
+ every scalar coefficient is independently mapped to one of \\(N_{cb}\\) discrete levels.
56
+
57
+
58
+ If every combination of codewords is a token, the vocabulary size is \\(N_{cb}^{N_q}\\), and each token needs \\(N_q\log_2 N_{cb}\\) bits. The overall bitrate (bits/s, BPS) is simply \\(f_r \times N_q \log_2 N_{cb}\\).
59
+ We aim to push this bitrate as low as possible without hurting audio fidelity.
60
+
61
+ ## What Makes Ours Better
62
+
63
+ - **Low Frame Rate**: Runs at justβ€―25β€―fps, halving the frame rate of many baselines while preserving high audio quality.
64
+ - **Unified 24 kHz Training**: A single model jointly trained on speech, music, and sound‑event data, capturing both semantic and acoustic nuances and greatly simplifying downstream audio‑language‑model training.
65
+ - **Fast Inference**: A non‑diffusion encoder/decoder that processes batches quickly, making it practical for real-time or large-scale tasks.
66
+
67
+
68
+ ## Evaluation Data and Metrics
69
+
70
+ We test on four subsets:
71
+
72
+ - **Speech, Music and Sound Event**: Include 1,000 clips per category, with each clip lasting 10 seconds. Clips are randomly sampled from [DAPS](https://ccrma.stanford.edu/~gautham/Site/daps.html) (Speech), [MUSDB](https://sigsep.github.io/datasets/musdb.html) (Music), and [AudioSet](https://research.google.com/audioset/index.html) (Sound Event).
73
+
74
+ - **Audiophile**: Contains 150 clips, each 30 seconds long, curated from eleven high-fidelity test discs that were designed for perceptual listening tests. The clips feature both high-quality music and sound events.
75
+
76
+ We measure:
77
+
78
+ - **Acoustic Quality**: Acoustic reconstruction error between the original and reconstructed audio.
79
+ - **Semantic Integrity**: Degree of semantic preservation, evaluated on the English and Chinese subsets of [SeedTTS](https://arxiv.org/abs/2406.02430)[15].
80
+ - **Aesthetics**: SOTA unified model-based quality metrics computed with [Meta Audiobox Aesthetics](https://github.com/facebookresearch/audiobox-aesthetics)[8].
81
+
82
+
83
+ We compare our tokenizer with a wide range of baselines, from tokenizers mainly built for better acoustic reconstruction and compression rate, to those focused on semantic integrity, and to tokenizers used in existing large audio language models. We also compare with tokenizers that are pretrained specifically on speech or on music.
84
+
85
+
86
+ The tables below summarize the tokenizers evaluated. As shown, our tokenizer achieves a well-rounded balance of efficiency, semantic fidelity, and acoustic quality.
87
+
88
+ ### Acoustic Evaluation
89
+
90
+ This table reports the Short‑Time Fourier Transform (STFT) distance between the original and reconstructed audio. Baselines are listed chronologically and grouped by whether semantic distillation (SD) is applied. Despite DAC’s top acoustic quality at 12Γ— the bitrate, our tokenizer leads all other baselines.
91
+
92
+
93
+ | Tokenizer | πŸ’¬ | 🎡 | πŸ₯ | SD | \\(f_s\\) | \\(f_r\\) | BPS<sup>*</sup> (k) ↓ | Speech ↓ | Sound Event ↓ | Music ↓ | Audiophile ↓ |
94
+ |-----------|----|----|----|----|-------|-------|--------------------------|----------|----------------|--------|--------------|
95
+ | [Encodec](https://huggingface.co/facebook/encodec_24khz)[3] | βœ“ | βœ“ | βœ“ | | 24 | 75 | 24 | 1.96 | 2.65 | 2.52 | 2.30 |
96
+ | [DAC](https://huggingface.co/hance-ai/descript-audio-codec-24khz)[2] | βœ“ | βœ“ | βœ“ | | 24 | 75 | 24 | **1.13** | **1.45** | **1.34** | **1.62** |
97
+ | [SNAC-24k](https://huggingface.co/hubertsiuzdak/snac_24khz)[6] | βœ“ | | | | 24 | (12, 23, 47) | 0.98 | 1.92 | 2.69 | 2.54 | 2.52 |
98
+ | [SNAC-44k](https://huggingface.co/hubertsiuzdak/snac_44khz)[6] | | βœ“ | βœ“ | | 44.1 | (14, 29, 57, 115) | 2.6 | 1.83 | 2.25 | 2.05 | 2.00 |
99
+ | [WavTokenizer](https://huggingface.co/novateur/WavTokenizer-medium-music-audio-75token/blob/main/wavtokenizer_medium_music_audio_320_24k_v2.ckpt)[7] | | βœ“ | βœ“ | | 24 | 75 | 0.9 | 1.93 | 2.44 | 2.17 | 2.15 |
100
+ | [WavTokenizer (Speech)](https://huggingface.co/novateur/WavTokenizer-large-speech-75token/tree/main)[7] | βœ“ | | | | 24 | 75 | 0.9 | 1.78 | 2.47 | 2.42 | 2.47 |
101
+ | [MuCodec](https://huggingface.co/haoheliu/audioldm_48k/tree/main)[11] | | βœ“ | | | 48 | 25 | 0.35 | 2.87 | 3.69 | 3.36 | 2.97 |
102
+ | [FlowDec-75m](https://github.com/facebookresearch/FlowDec?tab=readme-ov-file)[12] | βœ“ | βœ“ | βœ“ | | 48 | 75 | 7.5 | 1.73 | 2.14 | 2.01 | 2.03 |
103
+ | [FlowDec-25s](https://github.com/facebookresearch/FlowDec?tab=readme-ov-file)[12] | βœ“ | βœ“ | βœ“ | | 48 | 25 | 4 | 1.94 | 2.42 | 2.25 | 2.33 |
104
+ | [SpeechTokenizer](https://huggingface.co/fnlp/SpeechTokenizer/tree/main/speechtokenizer_hubert_avg)[14] | βœ“ | | | βœ“ | 16 | 50 | 4 | 3.21 | 3.58 | 3.65 | 3.69 |
105
+ | [SemantiCodec](https://huggingface.co/haoheliu/SemantiCodec/tree/main/semanticodec_tokenrate_100)[5] | βœ“ | βœ“ | βœ“ | βœ“ | 16 | 100 | 1.35 | 3.05 | 3.28 | 3.24 | 3.18 |
106
+ | [Mimi](https://huggingface.co/docs/transformers/en/model_doc/mimi)[13] | βœ“ | | | βœ“ | 24 | 12.5 | 4.4 | 1.77 | 2.40 | 2.30 | 2.15 |
107
+ | [XCodec](https://huggingface.co/ZhenYe234/xcodec/blob/main/config_hubert_general.yaml)[1] | βœ“ | βœ“ | βœ“ | βœ“ | 16 | 50 | 4 | 2.95 | 3.16 | 3.00 | 3.03 |
108
+ | [CosyVoice 2](https://huggingface.co/FunAudioLLM/CosyVoice2-0.5B)[13] | βœ“ | | | βœ“ | 16 | 25 | -<sup>**</sup>| 2.30 | 3.30 | 3.14 | 3.25 |
109
+ | [XCodec2](https://huggingface.co/HKUST-Audio/xcodec2/blob/main/ckpt/epoch%3D4-step%3D1400000.ckpt)[9] | βœ“ | | | βœ“ | 16 | 50 | 0.8 | 3.06 | 3.72 | 3.62 | 3.64 |
110
+ | [XY](https://huggingface.co/fnlp/XY_Tokenizer_TTSD_V0/tree/main)[10] | βœ“ | | | βœ“ | 24 | 12.5 | 1 | 1.89 | 2.51 | 2.40 | 2.26 |
111
+ | Ours | βœ“ | βœ“ | βœ“ | βœ“ | 24 | 25 | 2 | **1.62** | **2.03** | **1.85** | **1.80** |
112
+
113
+
114
+
115
+ <sup>* Bits-per-second is calculated according to the checkpoint the author provided.</sup>
116
+
117
+ <sup>** CosyVoice 2 uses the continuous feature as the conditioning; we include it for completeness.</sup>
118
+
119
+
120
+ ### Semantic Evaluation
121
+ [SeedTTS](https://github.com/BytedanceSpeech/seed-tts-eval) is a dataset that includes prompt/target audio and texts. We reconstruct the target audio, and use the word error rate (WER) and speaker similarity (SIM) metrics to evaluate the semantic integrity. SIM is calculated by the similarity between the prompt audio and reconstructed target audio with [WavLM-large](https://drive.google.com/file/d/1-aE1NfzpRCLxA4GUxX9ITI3F9LlbtEGP/view) as the embedding model.
122
+
123
+ The following table compares our tokenizer with semantic-distillation-trained baselines and shows that it delivers performance comparable to tokenizers operating at 2.2Γ— our model’s bitrate.
124
+
125
+ | Model | BPS (k) | en WER ↓ | en SIM ↑ | zh WER ↓ | zh SIM ↑ |
126
+ |------------------|---------|------------|------------|------------|------------|
127
+ | [SpeechTokenizer](https://huggingface.co/fnlp/SpeechTokenizer/tree/main/speechtokenizer_hubert_avg) | 4 | 2.82 | 0.63 | 2.04 | 0.65 |
128
+ | [SemantiCodec](https://huggingface.co/haoheliu/SemantiCodec/tree/main/semanticodec_tokenrate_100) | 1.35 | 3.46 | 0.56 | 2.18 | 0.60 |
129
+ | [Mimi](https://huggingface.co/docs/transformers/en/model_doc/mimi) | 4.4 | **2.35** | **0.70** | **1.48** | **0.72** |
130
+ | [XCodec](https://huggingface.co/ZhenYe234/xcodec/blob/main/config_hubert_general.yaml) | 4.0 | 2.68 | 0.63 | 1.66 | 0.66 |
131
+ | [CosyVoice 2](https://huggingface.co/FunAudioLLM/CosyVoice2-0.5B) | - | 3.17 | 0.65 | 2.11 | 0.70 |
132
+ | [XCodec2](https://huggingface.co/HKUST-Audio/xcodec2/blob/main/ckpt/epoch%3D4-step%3D1400000.ckpt) | 0.8 | 2.74 | 0.62 | 1.91 | 0.67 |
133
+ | [XY-MOSS-TTSD](https://huggingface.co/fnlp/XY_Tokenizer_TTSD_V0/tree/main) | 1.0 | 2.72 | 0.61 | 1.58 | 0.67 |
134
+ | Ours | 2.0 | 2.52 | 0.67 | **1.48** | 0.71 |
135
+
136
+
137
+
138
+ ### Audiobox Aesthetics Evaluation
139
+
140
+ This model-based evaluation[8] further demonstrates the superiority of our tokenizer. CU denotes the Content Usefulness and CE denotes the Content Enjoyment; both are rated on a 1-10 scale. Notably, our tokenizer performs best on the Audiophile set, demonstrating a clear advantage when the original audio quality is high.
141
+
142
+
143
+ | Model | BPS (k) | Music CE ↑ | Music CU ↑ | Sound Event CE ↑ | Sound Event CU ↑ | Speech CE ↑ | Speech CU ↑ | Audiophile CE ↑ | Audiophile CU ↑ |
144
+ |------------------|---------|--------------|--------------|--------------------|--------------------|---------------|---------------|--------------------|--------------------|
145
+ | Origin | - | 6.20 | 7.10 | 4.47 | 5.64 | 5.03 | 4.87 | 7.17 | 7.65 |
146
+ | [SpeechTokenizer](https://huggingface.co/fnlp/SpeechTokenizer/tree/main/speechtokenizer_hubert_avg) | 4.0 | 3.55 | 5.22 | 3.03 | 4.50 | 4.68 | 4.58 | 3.59 | 5.07 |
147
+ | [SemantiCodec](https://huggingface.co/haoheliu/SemantiCodec/tree/main/semanticodec_tokenrate_100) | 1.35 | 6.01 | 6.83 | 4.22 | 5.30 | 4.28 | 4.12 | 6.97 | 7.43 |
148
+ | [Mimi](https://huggingface.co/docs/transformers/en/model_doc/mimi) | 4.4 | 6.01 | 6.83 | 4.26 | 5.35 | 4.87 | 4.72 | 6.80 | 7.29 |
149
+ | [XCodec](https://huggingface.co/ZhenYe234/xcodec/blob/main/config_hubert_general.yaml) | 4.0 | **6.30** | **7.10** | **4.43** | 5.45 | **4.96** | **4.79** | 7.06 | 7.49 |
150
+ | [CosyVoice 2](https://huggingface.co/FunAudioLLM/CosyVoice2-0.5B) | - | 5.21 | 6.14 | 4.08 | 4.73 | **4.91** | **4.75** | 5.97 | 6.56 |
151
+ | [XCodec2](https://huggingface.co/HKUST-Audio/xcodec2/blob/main/ckpt/epoch%3D4-step%3D1400000.ckpt) | 0.8 | 4.38 | 5.66 | 3.43 | 4.63 | **4.93** | **4.78** | 4.56 | 5.46 |
152
+ | [XY-MOSS-TTSD](https://huggingface.co/fnlp/XY_Tokenizer_TTSD_V0/tree/main) | 1.0 | 5.77 | 6.80 | 4.23 | 5.34 | 4.88 | 4.72 | 6.95 | 7.48 |
153
+ | Ours | 2.0 | **6.35** | **7.15** | **4.47** | **5.51** | 4.90 | 4.70 | **7.21** | **7.66** |
154
+
155
+
156
+
157
+ Note that since some tokenizers are trained on 16 kHz data, we upsample their audio outputs to 24 kHz before computing metrics. Different upsampling methods may cause slight variations (e.g., 4.36 vs. 4.43 for XCodec Sound Event CE). We report the best results we could obtain and highlight any results within 0.05 of the best one.
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+ <!-- xcodec [1]
166
+ dac [2]
167
+ encodec [3]
168
+ moshi [4]
169
+ semanticodec [5]
170
+ snac [6]
171
+ wavtokenizer [7]
172
+ xcodec [8]
173
+ xcodec2 [9]
174
+ xy-tokenizer [10]
175
+ mucodec [11]
176
+ flowdec [12]
177
+ cosyvoice2 [13]
178
+ speechtokenizer [14] -->
179
+
180
+
181
+
182
+
183
+ ## Reference
184
+ [1] [Ye, Zhen, et al. "Codec does matter: Exploring the semantic shortcoming of codec for audio language model." Proceedings of the AAAI Conference on Artificial Intelligence. Vol. 39. No. 24. 2025.](https://arxiv.org/abs/2408.17175)
185
+
186
+ [2] [Kumar, Rithesh, et al. "High-fidelity audio compression with improved rvqgan." Advances in Neural Information Processing Systems 36 (2023): 27980-27993.](https://dl.acm.org/doi/10.5555/3666122.3667336)
187
+
188
+ [3] [DΓ©fossez, Alexandre, et al. "High fidelity neural audio compression." arXiv preprint arXiv:2210.13438 (2022).](https://arxiv.org/abs/2210.13438)
189
+
190
+ [4] [DΓ©fossez, Alexandre, et al. "Moshi: a speech-text foundation model for real-time dialogue." arXiv preprint arXiv:2410.00037 (2024).](https://arxiv.org/abs/2410.00037)
191
+
192
+ [5] [Liu, Haohe, et al. "Semanticodec: An ultra low bitrate semantic audio codec for general sound." IEEE Journal of Selected Topics in Signal Processing (2024).](https://ieeexplore.ieee.org/document/10768970)
193
+
194
+ [6] [Siuzdak, Hubert, Florian GrΓΆtschla, and Luca A. LanzendΓΆrfer. "Snac: Multi-scale neural audio codec." arXiv preprint arXiv:2410.14411 (2024).](https://arxiv.org/abs/2410.14411)
195
+
196
+ [7] [Ji, Shengpeng, et al. "Wavtokenizer: an efficient acoustic discrete codec tokenizer for audio language modeling." arXiv preprint arXiv:2408.16532 (2024).](https://arxiv.org/abs/2408.16532)
197
+
198
+ [8] [Tjandra, Andros, et al. "Meta audiobox aesthetics: Unified automatic quality assessment for speech, music, and sound." arXiv preprint arXiv:2502.05139 (2025).](https://arxiv.org/abs/2502.05139)
199
+
200
+ [9] [Ye, Zhen, et al. "Llasa: Scaling Train-Time and Inference-Time Compute for Llama-based Speech Synthesis." arXiv preprint arXiv:2502.04128 (2025).](https://arxiv.org/abs/2502.04128)
201
+
202
+ [10] [Gong, Yitian, et al. "XY-Tokenizer: Mitigating the Semantic-Acoustic Conflict in Low-Bitrate Speech Codecs." arXiv preprint arXiv:2506.23325 (2025).](https://arxiv.org/abs/2506.23325)
203
+
204
+ [11] [Xu, Yaoxun, et al. "MuCodec: Ultra Low-Bitrate Music Codec." arXiv preprint arXiv:2409.13216 (2024).](https://arxiv.org/abs/2409.13216)
205
+
206
+ [12] [Welker, Simon, et al. "FlowDec: A flow-based full-band general audio codec with high perceptual quality." arXiv preprint arXiv:2503.01485 (2025).](https://arxiv.org/abs/2503.01485)
207
+
208
+ [13] [Du, Zhihao, et al. "Cosyvoice 2: Scalable streaming speech synthesis with large language models." arXiv preprint arXiv:2412.10117 (2024).](https://arxiv.org/abs/2412.10117)
209
+
210
+ [14] [Zhang, Xin, et al. "Speechtokenizer: Unified speech tokenizer for speech large language models." arXiv preprint arXiv:2308.16692 (2023).](https://arxiv.org/abs/2308.16692)
211
+
212
+ [15] [Anastassiou, Philip, et al. "Seed-tts: A family of high-quality versatile speech generation models." arXiv preprint arXiv:2406.02430 (2024).](https://arxiv.org/abs/2406.02430)
acoustic_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9fbc3a4c81c7753ace690104b320d9ef41eababc50196084a7b2c3bd2e291f16
3
+ size 205546480
fp16/acoustic_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e24702e1a492d619fe7d1fe0c7cd3d530eba8144f5da826630e4dd97fec1b5fc
3
+ size 295846
fp16/acoustic_encoder.onnx.data ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b3725792aa9cc9ef9779955a648c87444f3d700a067c7fdd68cf006e26992073
3
+ size 102615039
fp16/higgs_decoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f2e1ba8ede642099a4151d0d0762eebf9ba996a5821a2205005afc0a2e4c820a
3
+ size 308494
fp16/higgs_decoder.onnx.data ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5be7ff51d117dd1cd001b87ec6e6e93f61cbe923355c50841a15fcaf19f64a19
3
+ size 43100160
fp16/model_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "onnxmodel",
3
+ "config": {
4
+ "model_path": "D:\\Projects\\olive-recipes\\OmniVoice\\higgs\\models",
5
+ "onnx_file_name": "higgs_decoder.onnx",
6
+ "inference_settings": null,
7
+ "use_ort_extensions": false,
8
+ "external_initializers_file_name": null,
9
+ "constant_inputs_file_name": null,
10
+ "model_attributes": null
11
+ }
12
+ }
fp16/quantizer_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3c1fd5d644b67ef532022f5f9558a6a30b495be92013918d33ce2f6be3d8f87c
3
+ size 6091791
fp16/semantic_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c24e3d4de75911dcb25adf3a993c9fd5689dfb4c97df02dcc82e58ab82ee30d7
3
+ size 334295
fp16/semantic_encoder.onnx.data ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:90080ded4fe1e847a9b924feea365ad2e9c04fa93569d34e6d6fa7218ee9a238
3
+ size 218235902
higgs_audio_tokenizer_architecture.png ADDED

Git LFS Details

  • SHA256: f7c0177e38dd9c873acf8ac55c159ce65ba50970cbeba9663582da4698037447
  • Pointer size: 131 Bytes
  • Size of remote file: 117 kB
higgs_decoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:601a69b103986d47a91c21bcffc9c8eef8aa462d0267256efff75033fa25cdff
3
+ size 86500102
higgs_inference.py ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Standalone Higgs Audio V2 Tokenizer β€” ONNX inference.
3
+
4
+ Encodes audio to discrete codec codes and decodes codes back to audio,
5
+ using the four exported ONNX sub-models:
6
+
7
+ acoustic_encoder.onnx β€” DAC encoder: (1,1,T_24k) β†’ (1,256,T_frames)
8
+ semantic_encoder.onnx β€” HuBERT encoder: (1,T_16k) β†’ (1,768,T_frames)
9
+ quantizer_encoder.onnx β€” RVQ encode: (1,256,T)+(1,768,T) β†’ (8,1,T)
10
+ higgs_decoder.onnx β€” DAC decode: (8,1,T) β†’ (1,1,T_24k)
11
+
12
+ No PyTorch, no transformers required at runtime β€” only onnxruntime.
13
+
14
+ Usage:
15
+ # Round-trip encode β†’ decode (sanity check)
16
+ python higgs_inference.py --input speech.wav --output reconstructed.wav
17
+
18
+ # Encode only β†’ save codes as .npy
19
+ python higgs_inference.py --input speech.wav --encode-only --codes-out codes.npy
20
+
21
+ # Decode only from saved codes
22
+ python higgs_inference.py --decode-only --codes-in codes.npy --output decoded.wav
23
+
24
+ # Use a different models directory
25
+ python higgs_inference.py --models-dir path/to/higgs/models --input speech.wav --output out.wav
26
+ """
27
+
28
+ import argparse
29
+ import sys
30
+ from pathlib import Path
31
+
32
+ import numpy as np
33
+
34
+ # ---------------------------------------------------------------------------
35
+ # Constants (from audio_tokenizer/config.json)
36
+ # ---------------------------------------------------------------------------
37
+ SR_24K = 24_000 # acoustic DAC sample rate
38
+ SR_16K = 16_000 # HuBERT semantic sample rate
39
+ HOP_LENGTH = 960 # DAC downsampling factor: product of [8,5,4,2,3]
40
+ D_ACOUSTIC = 256 # acoustic encoder output channels
41
+ D_SEMANTIC = 768 # semantic encoder output channels
42
+ N_CODEBOOKS = 8 # RVQ codebooks
43
+ CODEBOOK_SIZE = 1024 # entries per codebook
44
+ DEFAULT_MODELS_DIR = Path(__file__).parent / "higgs" / "models"
45
+
46
+
47
+ # =============================================================================
48
+ # Audio I/O
49
+ # =============================================================================
50
+
51
+ def load_wav(path: str, target_sr: int) -> np.ndarray:
52
+ """Load an audio file, resample to target_sr, mix to mono.
53
+
54
+ Returns float32 array in [-1, 1], shape (T,).
55
+ Tries torchaudio first (accurate), falls back to scipy.
56
+ """
57
+ path = str(path)
58
+
59
+ # --- torchaudio (preferred) ---
60
+ try:
61
+ import torchaudio, torch
62
+ wav, sr = torchaudio.load(path)
63
+ if sr != target_sr:
64
+ wav = torchaudio.functional.resample(wav, sr, target_sr)
65
+ if wav.shape[0] > 1:
66
+ wav = wav.mean(0, keepdim=True)
67
+ return wav.squeeze(0).numpy().astype(np.float32)
68
+ except ImportError:
69
+ pass
70
+
71
+ # --- scipy fallback ---
72
+ from scipy.io import wavfile
73
+ from scipy.signal import resample_poly
74
+ from math import gcd
75
+ sr, data = wavfile.read(path)
76
+ if data.dtype == np.int16:
77
+ data = data.astype(np.float32) / 32768.0
78
+ elif data.dtype == np.int32:
79
+ data = data.astype(np.float32) / 2147483648.0
80
+ elif data.dtype != np.float32:
81
+ data = data.astype(np.float32)
82
+ if data.ndim > 1:
83
+ data = data.mean(axis=1)
84
+ if sr != target_sr:
85
+ g = gcd(target_sr, sr)
86
+ data = resample_poly(data, target_sr // g, sr // g).astype(np.float32)
87
+ return data
88
+
89
+
90
+ def save_wav(path: str, waveform: np.ndarray, sr: int = SR_24K):
91
+ """Save float32 numpy waveform as 16-bit PCM WAV."""
92
+ path = str(path)
93
+ try:
94
+ import soundfile as sf
95
+ sf.write(path, waveform, sr, subtype="PCM_16")
96
+ return
97
+ except ImportError:
98
+ pass
99
+ from scipy.io import wavfile
100
+ pcm = np.clip(waveform, -1.0, 1.0)
101
+ wavfile.write(path, sr, (pcm * 32767).astype(np.int16))
102
+
103
+
104
+ # =============================================================================
105
+ # ONNX session loader
106
+ # =============================================================================
107
+
108
+ class HiggsOnnxSessions:
109
+ """Holds the four Higgs ONNX InferenceSession objects."""
110
+
111
+ MODEL_FILES = {
112
+ "acoustic_encoder": "acoustic_encoder.onnx",
113
+ "semantic_encoder": "semantic_encoder.onnx",
114
+ "quantizer_encoder": "quantizer_encoder.onnx",
115
+ "higgs_decoder": "higgs_decoder.onnx",
116
+ }
117
+
118
+ def __init__(self, models_dir: str, provider: str = "CPUExecutionProvider"):
119
+ import onnxruntime as ort
120
+ models_dir = Path(models_dir)
121
+ opts = ort.SessionOptions()
122
+ opts.log_severity_level = 3 # suppress INFO / WARNING noise
123
+
124
+ self.sessions = {}
125
+ for key, filename in self.MODEL_FILES.items():
126
+ p = models_dir / filename
127
+ if not p.exists():
128
+ raise FileNotFoundError(
129
+ f"Missing: {p}\n"
130
+ f"Export Higgs models first:\n"
131
+ f" cd OmniVoice && python optimize.py --higgs-only"
132
+ )
133
+ self.sessions[key] = ort.InferenceSession(
134
+ str(p), sess_options=opts, providers=[provider]
135
+ )
136
+ print(f"Loaded {len(self.sessions)} Higgs ONNX sessions from {models_dir}")
137
+
138
+ def __getitem__(self, key):
139
+ return self.sessions[key]
140
+
141
+
142
+ # =============================================================================
143
+ # dtype helper β€” cast float32 inputs to whatever the ONNX session expects
144
+ # =============================================================================
145
+
146
+ _ORT_TO_NP = {
147
+ "tensor(float16)": np.float16,
148
+ "tensor(float)": np.float32,
149
+ "tensor(double)": np.float64,
150
+ "tensor(int64)": np.int64,
151
+ "tensor(int32)": np.int32,
152
+ }
153
+
154
+
155
+ def _cast_feed(feed: dict, sess) -> dict:
156
+ """Auto-cast numpy arrays to the dtype expected by the ONNX session.
157
+
158
+ OnnxFloatToFloat16 converts all float inputs/outputs to float16. Feeding
159
+ float32 to such a model raises INVALID_ARGUMENT. This inspects the session
160
+ input metadata and casts each value to the declared type.
161
+ """
162
+ type_map = {inp.name: _ORT_TO_NP.get(inp.type) for inp in sess.get_inputs()}
163
+ out = {}
164
+ for k, v in feed.items():
165
+ tgt = type_map.get(k)
166
+ if tgt is not None and isinstance(v, np.ndarray) and v.dtype != tgt:
167
+ v = v.astype(tgt)
168
+ out[k] = v
169
+ return out
170
+
171
+
172
+ # =============================================================================
173
+ # Encode: audio β†’ codec codes
174
+ # =============================================================================
175
+
176
+ def encode(sessions: HiggsOnnxSessions, wav_path: str) -> np.ndarray:
177
+ """Encode an audio file to RVQ codec codes.
178
+
179
+ Pipeline:
180
+ wav_path (24 kHz) β†’ acoustic_encoder β†’ (1, 256, T_a)
181
+ wav_path (16 kHz) β†’ semantic_encoder β†’ (1, 768, T_s)
182
+ align T_s β†’ T_a (linear interpolation along time axis)
183
+ concat channels β†’ quantizer_encoder β†’ (8, 1, T_a) int64
184
+
185
+ Returns:
186
+ codes: np.ndarray shape (8, 1, T_a) dtype int64
187
+ T_a is the number of codec frames (25 per second of 24 kHz audio).
188
+ """
189
+ # 1. Load audio at both sample rates
190
+ wav24 = load_wav(wav_path, SR_24K) # (T_24k,)
191
+ wav16 = load_wav(wav_path, SR_16K) # (T_16k,)
192
+
193
+ dur = len(wav24) / SR_24K
194
+ print(f" Audio: {dur:.2f}s "
195
+ f"({len(wav24)} samples @ {SR_24K} Hz, "
196
+ f"{len(wav16)} samples @ {SR_16K} Hz)")
197
+
198
+ # 2. Acoustic encoder β†’ (1, 256, T_a)
199
+ waveform_24k = wav24[None, None, :] # (1, 1, T_24k)
200
+ _ae_sess = sessions["acoustic_encoder"]
201
+ acoustic_feat = _ae_sess.run(
202
+ ["acoustic_features"],
203
+ _cast_feed({"waveform_24k": waveform_24k}, _ae_sess)
204
+ )[0] # (1, 256, T_a)
205
+ T_a = acoustic_feat.shape[2]
206
+ print(f" acoustic_encoder β†’ {acoustic_feat.shape} ({T_a} frames, {T_a/dur:.1f} fps)")
207
+
208
+ # 3. Semantic encoder β†’ (1, 768, T_s)
209
+ waveform_16k = wav16[None, :] # (1, T_16k)
210
+ _se_sess = sessions["semantic_encoder"]
211
+ semantic_feat = _se_sess.run(
212
+ ["semantic_features"],
213
+ _cast_feed({"waveform_16k": waveform_16k}, _se_sess)
214
+ )[0] # (1, 768, T_s)
215
+ T_s = semantic_feat.shape[2]
216
+ print(f" semantic_encoder β†’ {semantic_feat.shape} ({T_s} frames, {T_s/dur:.1f} fps)")
217
+
218
+ # 4. Frame alignment check
219
+ # The fixed semantic_encoder wrapper applies semantic_downsample_factor=2 and
220
+ # the (160,160) padding internally, matching _extract_semantic_features() exactly.
221
+ # T_s == T_a naturally for typical audio. Trim on rare off-by-one edge cases.
222
+ if T_s != T_a:
223
+ T = min(T_a, T_s)
224
+ acoustic_feat = acoustic_feat[:, :, :T]
225
+ semantic_feat = semantic_feat[:, :, :T]
226
+ print(f" [warn] T_a={T_a} != T_s={T_s}, trimmed both to T={T}")
227
+
228
+ # 5. Quantizer encoder β†’ (8, 1, T_a) int64
229
+ _qe_sess = sessions["quantizer_encoder"]
230
+ codes = _qe_sess.run(
231
+ ["codes"],
232
+ _cast_feed({
233
+ "acoustic_features": acoustic_feat, # (1, 256, T_a)
234
+ "semantic_features": semantic_feat, # (1, 768, T_a)
235
+ }, _qe_sess)
236
+ )[0] # (8, 1, T_a)
237
+ print(f" quantizer_encoder β†’ {codes.shape} "
238
+ f"({N_CODEBOOKS} codebooks Γ— {T_a} frames) "
239
+ f"value range [{codes.min()}, {codes.max()}]")
240
+
241
+ return codes
242
+
243
+
244
+ # =============================================================================
245
+ # Decode: codec codes β†’ audio
246
+ # =============================================================================
247
+
248
+ def decode(sessions: HiggsOnnxSessions, codes: np.ndarray) -> np.ndarray:
249
+ """Decode RVQ codec codes back to a waveform.
250
+
251
+ Args:
252
+ codes: np.ndarray shape (8, 1, T_frames) dtype int64
253
+
254
+ Returns:
255
+ waveform: np.ndarray shape (T_samples,) float32 at 24 kHz
256
+ """
257
+ if codes.ndim != 3 or codes.shape[0] != N_CODEBOOKS:
258
+ raise ValueError(
259
+ f"codes must have shape (8, 1, T_frames), got {codes.shape}"
260
+ )
261
+ if codes.dtype != np.int64:
262
+ codes = codes.astype(np.int64)
263
+
264
+ T_frames = codes.shape[2]
265
+ expected_dur = T_frames * HOP_LENGTH / SR_24K
266
+
267
+ _hd_sess = sessions["higgs_decoder"]
268
+ waveform = _hd_sess.run(
269
+ ["waveform_24k"],
270
+ _cast_feed({"codes": codes}, _hd_sess)
271
+ )[0] # (1, 1, T_samples)
272
+
273
+ waveform = waveform.squeeze() # (T_samples,)
274
+ actual_dur = len(waveform) / SR_24K
275
+ print(f" higgs_decoder β†’ {waveform.shape} "
276
+ f"({actual_dur:.2f}s expected {expected_dur:.2f}s)")
277
+
278
+ return waveform
279
+
280
+
281
+ # =============================================================================
282
+ # Convenience: round-trip encode + decode
283
+ # =============================================================================
284
+
285
+ def encode_decode(sessions: HiggsOnnxSessions, wav_path: str) -> tuple:
286
+ """Encode audio to codes then decode back to waveform.
287
+
288
+ Returns:
289
+ codes: np.ndarray (8, 1, T_frames) int64
290
+ waveform: np.ndarray (T_samples,) float32
291
+ """
292
+ print("[Encode]")
293
+ codes = encode(sessions, wav_path)
294
+ print("[Decode]")
295
+ waveform = decode(sessions, codes)
296
+ return codes, waveform
297
+
298
+
299
+ # =============================================================================
300
+ # CLI
301
+ # =============================================================================
302
+
303
+ def main():
304
+ parser = argparse.ArgumentParser(
305
+ description="Higgs Audio V2 Tokenizer β€” standalone ONNX encode/decode"
306
+ )
307
+ parser.add_argument(
308
+ "--models-dir", default=str(DEFAULT_MODELS_DIR),
309
+ help=f"Higgs ONNX models directory (default: {DEFAULT_MODELS_DIR})"
310
+ )
311
+ parser.add_argument(
312
+ "--input", "-i", default=None,
313
+ help="Input audio file to encode (.wav or any format torchaudio/scipy supports)"
314
+ )
315
+ parser.add_argument(
316
+ "--output", "-o", default="output.wav",
317
+ help="Output WAV file for decoded audio (default: output.wav)"
318
+ )
319
+ parser.add_argument(
320
+ "--encode-only", action="store_true",
321
+ help="Only encode β€” save codes to --codes-out, do not decode"
322
+ )
323
+ parser.add_argument(
324
+ "--decode-only", action="store_true",
325
+ help="Only decode β€” load codes from --codes-in, skip encoding"
326
+ )
327
+ parser.add_argument(
328
+ "--codes-out", default="codes.npy",
329
+ help="Path to save encoded codes as .npy (default: codes.npy)"
330
+ )
331
+ parser.add_argument(
332
+ "--codes-in", default=None,
333
+ help="Path to load codes .npy for --decode-only mode"
334
+ )
335
+ parser.add_argument(
336
+ "--cuda", action="store_true",
337
+ help="Use CUDAExecutionProvider instead of CPU"
338
+ )
339
+ args = parser.parse_args()
340
+
341
+ provider = "CUDAExecutionProvider" if args.cuda else "CPUExecutionProvider"
342
+
343
+ # Validate argument combinations
344
+ if args.encode_only and args.decode_only:
345
+ parser.error("--encode-only and --decode-only are mutually exclusive")
346
+ if not args.decode_only and args.input is None:
347
+ parser.error("--input is required unless --decode-only is used")
348
+ if args.decode_only and args.codes_in is None:
349
+ parser.error("--codes-in is required when using --decode-only")
350
+
351
+ # Load ONNX sessions
352
+ sessions = HiggsOnnxSessions(args.models_dir, provider)
353
+
354
+ # -------------------------------------------------------------------------
355
+ if args.encode_only:
356
+ print(f"\nEncoding: {args.input}")
357
+ codes = encode(sessions, args.input)
358
+ np.save(args.codes_out, codes)
359
+ print(f"\nSaved codes β†’ {args.codes_out} shape={codes.shape} dtype={codes.dtype}")
360
+
361
+ # -------------------------------------------------------------------------
362
+ elif args.decode_only:
363
+ print(f"\nLoading codes from: {args.codes_in}")
364
+ codes = np.load(args.codes_in)
365
+ print(f" codes shape={codes.shape} dtype={codes.dtype}")
366
+ print(f"\nDecoding...")
367
+ waveform = decode(sessions, codes)
368
+ save_wav(args.output, waveform, SR_24K)
369
+ print(f"Saved WAV β†’ {args.output} ({len(waveform)/SR_24K:.2f}s @ {SR_24K} Hz)")
370
+
371
+ # -------------------------------------------------------------------------
372
+ else:
373
+ # Full round-trip
374
+ print(f"\nRound-trip encode β†’ decode")
375
+ print(f" Input : {args.input}")
376
+ print(f" Output: {args.output}")
377
+ codes, waveform = encode_decode(sessions, args.input)
378
+
379
+ # Optionally save codes
380
+ np.save(args.codes_out, codes)
381
+ print(f"\nSaved codes β†’ {args.codes_out}")
382
+
383
+ save_wav(args.output, waveform, SR_24K)
384
+ dur_in = len(load_wav(args.input, SR_24K)) / SR_24K
385
+ dur_out = len(waveform) / SR_24K
386
+ print(f"Saved WAV β†’ {args.output} ({dur_out:.2f}s, input was {dur_in:.2f}s)")
387
+ print(f"\nReconstruction note: codec compression (RVQ, 8 codebooks Γ— 1024 entries)")
388
+ print(f"at 25 fps introduces mild quality loss β€” this is expected.")
389
+
390
+
391
+ if __name__ == "__main__":
392
+ main()
model_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "onnxmodel",
3
+ "config": {
4
+ "model_path": "D:\\Projects\\olive-recipes\\OmniVoice\\higgs\\models\\higgs_decoder.onnx",
5
+ "onnx_file_name": null,
6
+ "inference_settings": null,
7
+ "use_ort_extensions": false,
8
+ "external_initializers_file_name": null,
9
+ "constant_inputs_file_name": null,
10
+ "model_attributes": null
11
+ }
12
+ }
quantizer_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4592311271a745da259513a33ae248f12dabc811e7942fcc0e0635da8b02ec37
3
+ size 12131293
semantic_encoder.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e3be47442600c7e5a29faa39b7f73b940243974848089b2ebe9717f83c1c7df
3
+ size 436736856