Instructions to use moonshine-ai/moonshine-streaming-small-ja with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use moonshine-ai/moonshine-streaming-small-ja with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("automatic-speech-recognition", model="moonshine-ai/moonshine-streaming-small-ja")# Load model directly from transformers import AutoProcessor, AutoModelForSpeechSeq2Seq processor = AutoProcessor.from_pretrained("moonshine-ai/moonshine-streaming-small-ja") model = AutoModelForSpeechSeq2Seq.from_pretrained("moonshine-ai/moonshine-streaming-small-ja", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Moonshine Streaming Small โ Japanese
Japanese streaming speech recognition, 112.9M parameters. Same architecture as moonshine-ai/moonshine-streaming-small, trained for Japanese with a 12,288-entry Japanese tokenizer. The Tiny model is a quarter of the size and about 2.5 CER worse.
Moonshine Streaming pairs a 50 Hz time-domain audio frontend with a sliding-window Transformer encoder, so it transcribes incrementally rather than waiting for an utterance to finish. It is intended for on-device use on edge-class hardware.
Checkpoint identity
| Checkpoint | ja12k_small_stageB_best.safetensors |
| Stage | B |
| Architecture | spindlier_prime_adapted |
| Tokenizer | tokenizer_ja12k.json, vocab 12,288 |
| Snapshot taken | 2026-08-23 |
| Parameters | 112.9M |
Usage
pip install --upgrade transformers datasets[audio]
from transformers import MoonshineStreamingForConditionalGeneration, AutoProcessor
import torch
model = MoonshineStreamingForConditionalGeneration.from_pretrained(
"moonshine-ai/moonshine-streaming-small-ja"
).eval()
processor = AutoProcessor.from_pretrained("moonshine-ai/moonshine-streaming-small-ja")
inputs = processor(audio, return_tensors="pt", sampling_rate=16000)
# Cap the output length. Like other seq2seq ASR models this one can fall into a
# repetition loop, and short or noisy clips are where it happens.
seq_lens = inputs.attention_mask.sum(dim=-1)
max_new_tokens = int((seq_lens * 6.5 / 16000).max().item()) + 2
generated = model.generate(**inputs, max_new_tokens=max_new_tokens)
print(processor.batch_decode(generated, skip_special_tokens=True)[0])
Pass the attention_mask. The encoder applies its per-layer sliding windows
only when it is given one; called without a mask it attends over the whole
utterance instead, which is a different model from the one that was trained. The
processor returns the mask, so the snippet above is the safe form. The processor
also pads audio to a whole number of 80-sample frames, which the frontend
requires.
Architecture
| Encoder | 10 layers, width 620, 8 heads, sliding windows (16, 4) on the first two and last two layers and (16, 0) between |
| Decoder | 10 layers, width 512, 8 heads, RoPE over 32 of each head's 64 dimensions |
| Frontend | 50 Hz features, CMVN, asinh compression, two causal stride-2 convolutions |
| Adapter | learned absolute positional embeddings, then a projection from 620 to 512 |
The lookahead layers give roughly 80 ms of lookahead; the intermediate layers have none.
Training data
Trained on a large-scale automatically labeled Japanese corpus:
- Podcast crawl, roughly 109,000 hours.
- YouTube crawl, roughly 50,000 hours.
These transcripts are pseudo-labels: they were produced by running a Whisper-family teacher model over crawled audio, not by human transcription. The model therefore inherits the teacher's error modes, including its handling of proper nouns, numerals and code-switching, and its transcription conventions for a language written without spaces. No human-verified transcript was used for the bulk of training.
Evaluation
Japanese is scored on character error rate with spaces removed
(cer_nospace), never WER. Japanese is written without spaces, so tokenization
differences alone can read as several hundred percent WER while the characters
are correct.
suite_ja is FLEURS Japanese (650 utterances) and ReazonSpeech Japanese (5,263).
Full panels, batch 8
| Panel | CER |
|---|---|
| macro | 16.765 |
Seeded 400-utterance sample, batch 1
Batch 1 is the honest number for deployment. Batched evaluation zero-pads short clips up to the longest in the batch, and that trailing silence flatters the model by more than a point on spontaneous speech.
| Panel | CER |
|---|---|
fleurs_ja |
7.99 |
reazonspeech_ja |
26.31 |
| macro | 17.15 |
This repository against the training checkpoint
These weights were converted from the neo training checkpoint, and the
conversion was checked by measurement rather than inspection: same seeded sample,
same batch size, same normalizer.
fleurs_ja |
reazonspeech_ja |
macro | |
|---|---|---|---|
| Training checkpoint | 7.99 | 26.31 | 17.153 |
| This repository | 7.90 | 26.69 | 17.295 |
397/400 and 383/400 transcripts are byte-identical, and excluding the handful of utterances where either side ran away the macro gap is 0.054. The residual comes from the frontend's 80-sample frame alignment, which this path pads and the training path does not.
Limitations
- Machine-labeled training data. See above; the model reproduces its teacher's mistakes as well as its strengths.
- Repetition loops on short clips. About 0.75% of ReazonSpeech utterances in the batch-1 sample run away. Cap the output length.
- Short-utterance sensitivity. Utterances with very short references are far harder than the macro number suggests, and are where numerically small changes produce large per-utterance swings.
- Evaluated only on read speech (FLEURS) and spontaneous speech (ReazonSpeech). No evaluation of telephony, children's speech, heavy dialect, or noisy far-field conditions.
Out-of-scope use
Not intended for non-consensual surveillance, speaker identification, or high-stakes decisions.
License
MIT.
- Downloads last month
- 17