File size: 4,216 Bytes
08329e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
---
license: other
license_name: cc-by-nc-4.0-and-apache-2.0
license_link: https://huggingface.co/afrispeech/Akiti-TTS
language:
- tw
library_name: phoonnx
pipeline_tag: text-to-speech
tags:
- onnx
- tts
- twi
- akan
- neutts
- neucodec
base_model:
- afrispeech/Akiti-TTS
- neuphonic/neucodec-onnx-decoder-int8
---

# phoonnx-neutts — Akiti-TTS (Asante Twi), ONNX

ONNX conversion of [afrispeech/Akiti-TTS](https://huggingface.co/afrispeech/Akiti-TTS),
an Asante Twi text-to-speech model, packaged for
[phoonnx](https://github.com/TigreGotico/phoonnx). This repository holds converted
weights only — no new training was done.

Akiti-TTS is a LoRA fine-tune of
[pnnbao-ump/VieNeu-TTS-0.3B](https://huggingface.co/pnnbao-ump/VieNeu-TTS-0.3B), which
comes from Neuphonic's NeuTTS Air family: a Qwen3 causal LM that emits
[NeuCodec](https://huggingface.co/neuphonic/neucodec) audio tokens.

## Files (`akiti-twi-onnx/`)

| File | What it is |
|---|---|
| `neutts_lm.onnx` + `neutts_lm.onnx.data` | Qwen3 backbone, fp32, KV-cached. **The graph needs its `.data` sidecar next to it.** |
| `neutts_lm_int8.onnx` | The same graph, dynamically quantized to int8. Smaller, but measurably lower quality — it puts the end-of-speech token in the top 5 at the first step, where fp32 does not. |
| `neucodec_decoder.onnx` | Copy of [neuphonic/neucodec-onnx-decoder-int8](https://huggingface.co/neuphonic/neucodec-onnx-decoder-int8) (Apache-2.0), unmodified. |
| `tokenizer.json` | The checkpoint's own BPE, copied from upstream. |
| `voices.json` | The nine voice presets, copied from [AfriSpeech/akiti-tts](https://github.com/AfriSpeech/akiti-tts) (MIT). |
| `neutts_onnx_meta.json` | Architecture summary written by the export script. |

## Graph contract

`neutts_lm.onnx` serves prefill and decode: the same graph with a different past length.

```
inputs   input_ids       int64 [1, S]         prompt tokens, or 1 token per step
         attention_mask  int64 [1, P + S]     ones over past and current tokens
         position_ids    int64 [1, S]         absolute positions, P .. P+S-1
         past_key_<i>    fp32  [1, 4, P, 64]  i in 0..27
         past_value_<i>  fp32  [1, 4, P, 64]
outputs  logits          fp32  [1, 66938]     last position only
         present_key_<i> / present_value_<i>  fp32 [1, 4, P + S, 64]
```

`neucodec_decoder.onnx` takes `codes` int32 `[1, 1, N]` and returns `audio` float32
`[1, 1, 480 * (N - 1)]` at 24 kHz — 50 codec tokens per second of audio.

## Prompt format

The LM is prompted with phonemes, not letters. Text is phonemized by espeak-ng using the
**`lfn`** (Lingua Franca Nova) voice, which is what the checkpoint was trained with;
espeak-ng has no Twi voice, and `lfn`'s five-vowel orthography reads Twi spelling closely.

```
<|TEXT_PROMPT_START|>{reference phones} {target phones}<|TEXT_PROMPT_END|>
<|SPEECH_GENERATION_START|>{<|speech_c|> for c in reference codes}
```

Generation continues that speech-token run until `<|SPEECH_GENERATION_END|>` or EOS.

## Fidelity

Exported with `scripts/conversion/neutts/export_neutts_onnx.py` in phoonnx. Against the
torch model on a fixed prompt, max absolute logit difference:

| | fp32 ONNX |
|---|---|
| prefill | 4.10e-05 |
| decode (8 steps) | 2.96e-05 |

The fp32 graph's top-5 next tokens on a real prompt are identical to torch's, in the same
order and to two decimal places.

## Licensing

The pieces carry different licenses, and one of them is inconsistent upstream. Read this
before using the model.

- **`afrispeech/Akiti-TTS` weights** — the Hugging Face model card declares
  **CC BY-NC 4.0** (non-commercial). The
  [GitHub README](https://github.com/AfriSpeech/akiti-tts) instead states the weights are
  Apache-2.0. These two statements disagree. This mirror records both and resolves
  neither; treat the stricter of the two (**non-commercial**) as binding until AfriSpeech
  clarifies. The GitHub repository's *code* is MIT, which is not in dispute.
- **`neucodec_decoder.onnx`** — Apache-2.0, from Neuphonic.
- **`voices.json`** — from the MIT-licensed AfriSpeech/akiti-tts repository.

Attribution: AfriSpeech / Ghana NLP (Akiti-TTS), pnnbao-ump (VieNeu-TTS-0.3B), Neuphonic
(NeuTTS Air, NeuCodec).