The large_ctc version of GigaAM-Multilingual was ported from PyTorch to MLX for native inference on Apple Silicon. The port provides four weight variants: FP16, INT8, INT6, and INT4.

The comparison covers storage, memory use, transcription speed, and the places where lower precision changes the output. The first audio sample contains the only difference between INT8 and FP16 across 255 Russian recordings.

The audio and reference transcript come from the Russian test split of google/fleurs, licensed under CC BY 4.0. Text was lowercased and stripped of punctuation for quality measurement.

Key results

4 weight variants FP16, INT8, INT6, INT4
1.95 s five-minute audio lowest latency with FP16
699 MB INT8 on disk 877 MB peak resident memory
+4.4% faster attention built-in SDPA, full INT8 pass
Measurements were taken on a MacBook Pro with M4 Pro. INT8 is the default because it offers the best balance of quality, size, and memory use.

How weight precision changes the transcript

INT8 changed one of 255 transcripts relative to FP16, INT6 changed seven, and INT4 changed 31. These counts show differences from FP16, so they do not always indicate an error against the reference. The two examples below show both cases: a spelling change in a common word and different Cyrillic renderings of a band name.

Another real sample · 8.34 s

One word changed only in INT4

Reference
Если вы хотите находиться рядом со сценой, вам нужно приехать заранее, чтобы найти место для кемпинга вблизи от музыки.
FP16 · INT8 · INT6
Matched the reference after normalization.
INT4
…чтобы найти место для кэмпинга вблизи от музыки.The reference uses “кемпинга”.
Another real sample · 5.46 s

Precision changed the Cyrillic spelling of Aerosmith

Reference
Группа Aerosmith отменила оставшиеся концерты в своем турне.
FP16 · INT8
Группа Аэросмит отменила оставшиеся концерты в своем турне.
INT6
Группа Айросмит отменила оставшиеся концерты в своем турне.
INT4
Группа Айро Смит отменила оставшиеся концерты в своем турне.The name was split into two words.
These samples were selected from outputs that differed. The reference writes Aerosmith in Latin characters, while the model renders its pronunciation in Cyrillic. A literal comparison therefore counts even an understandable rendering as different. Overall error frequency is measured with WER, or Word Error Rate, across the full dataset.

What is inside the model

GigaAM-Multilingual supports Russian, Kazakh, Kyrgyz, Uzbek, and English. The published large_ctc variant was selected for the port. It has about 600 million parameters and 24 Conformer blocks. These blocks find relationships in the audio. CTC, or Connectionist Temporal Classification, then turns their output into a character sequence without requiring a predefined alignment between every sound and point in time.

MLX runs computations on the CPU and GPU of Apple Silicon. Both processors use the Mac’s unified memory. To preserve the behavior of the original model, the MLX port reproduces the complete signal path: feature extraction, multidimensional array layouts, position handling, masking, and conversion of model output into text.

GigaAM-Multilingual large_ctc From waveform to text
Input Audio 16,000 samples per second
Features Frequency map frequencies over time
Time reduction Two convolutions four times fewer steps
Encoder 24 blocks about 585M parameters
Classifier CTC character probabilities
Output Text repeats and blanks removed
One Conformer block The same structure repeats 24 times
½ step Feed-forward block FFN: Linear → SiLU → Linear
long-range context Self-attention query, key, and value (Q, K, V)
local context Convolution pointwise and depthwise 1D convolutions
½ step Feed-forward block FFN: Linear → SiLU → Linear
block output Normalization LayerNorm
Two FFNs68.8% of parameters / 55.4% of time Attention17.2% of parameters / 25.5% of time Convolution12.9% of parameters / 17.1% of time
Linear weights: FP16, INT8, INT6, or INT4 Convolutions and normalization in Conformer remain FP16
The upper section shows the complete signal path. The lower section expands one of the 24 identical Conformer blocks and marks the layers with quantized weights. Sources: the Conformer paper and the GigaAM MLX implementation.
Signal path through the model
  1. Audio mono signal, 16 kHz
  2. Log-mel spectrogram frequencies and their change over time
  3. 2 convolutional layers the sequence becomes four times shorter
  4. 24 Conformer blocks FFNattentionconvolutionFFN
  5. CTC layer probability of each character at every step
  6. Decoding repeats and blank symbols are removed to produce text
Most computation happens in the 24 Conformer blocks. Each block passes data through two FFNs, uses attention to connect distant parts of the recording, and extracts local audio features with convolution.
Work map for the MLX version
  1. Audio Practical input added WAV, FLAC, MP3, M4A, and video; long recordings are split into chunks
  2. Features Rewritten in MLX windowing, spectrum, and mel filter were matched against PyTorch
  3. Time reduction Convolutions ported tensor shapes, masks, and weight layouts were checked separately
  4. 24 Conformer blocks Main area of work all layers were ported; linear weights received INT8, INT6, and INT4 variants; FFN, attention, and convolution were profiled separately SDPA, mx.compile(), chunk length, and batch processing were tested.
  5. CTC Model output reproduced log probabilities and character sequences were checked against the original
  6. Text Usable tool assembled CLI, subtitles, Python API, and a local server with a compatible API
The full signal path was ported to MLX. Quantization affects linear layers, which are concentrated mainly inside Conformer. Performance experiments focused on the same computationally heavy section.

A working port had to satisfy four conditions:

  1. regular transcription requires only MLX and an audio-reading library;
  2. FP32 and FP16 reproduce the original model within an acceptable numerical tolerance;
  3. every variant runs on the same public evaluation inputs;
  4. speed, file size, and memory are measured separately on identical recordings.

The work is based on the official ai-sage/GigaAM-Multilingual model and the salute-developers/GigaAM source code. The completed MLX version is published in ai-babai/gigaam-multilingual-mlx.

How parity with the original model was verified

The converter reads the official weight file and saves it in the safer safetensors format. Transcription itself runs on MLX. PyTorch is needed only for conversion and implementation comparisons.

Intermediate tensors, the multidimensional arrays inside the model, were compared first. Checks were placed after every major stage. This makes it possible to locate a divergence immediately, even when the final transcript happens to match.

  1. Pin the source code revision, weight file, preprocessing
  2. Compare tensors shapes and numerical deviations after key layers
  3. Compare text identical decoding on identical audio
  4. Measure quality WER on pinned public datasets
Each level is meaningful only after the previous one passes.

Quality evaluation uses pinned public sample lists and one text-normalization procedure: lowercasing, punctuation removal, and the same remaining transformations for every model. The original model, FP16, and quantized variants receive identical audio and reference transcripts. The first Russian suite contains 1,533 recordings from FLEURS, Russian LibriSpeech, and SOVA. The final multilingual-v1 suite uses 1,000 pinned FLEURS samples for each of Russian, Kazakh, Kyrgyz, Uzbek, and English.

The benchmark ran on a MacBook Pro with M4 Pro and 48 GB of unified memory under macOS 15.7.7. The original PyTorch implementation used Apple’s MPS acceleration with FP16 autocast. A five-minute Russian WAV was processed after model loading and a short warm-up. Every variant ran in a separate process.

WER measures substituted, deleted, and inserted words. A value near 5% can be read as roughly five corrections per hundred words. The full report calls the average across Russian, Kazakh, Kyrgyz, and Uzbek Core macro WER.

The source JSON also records CER, or Character Error Rate, and RTF, or Real-Time Factor. RTF is processing time divided by audio duration. An RTF below 1 means the model runs faster than real time. Lower is better in every numeric column below.

How precision affects size and speed

The official pytorch_model.bin stores all 824 tensors in FP32 and occupies 2.342 GB. Conversion to MLX changes the weights to FP16 and reduces the file to 1.171 GB. INT8, INT6, and INT4 are produced from MLX FP16 and use fewer bits. The 2.342 GB value describes the source weight file on disk. The PyTorch/MPS speed measurement used FP16 autocast for supported computations.

During quantization, each group of 64 weights receives a shared scale used to approximate the original values. The g64 label means that the group contains 64 weights. Every published variant has its own weights, description, checksum, and pinned revision.

Peak RSS, or Resident Set Size, is the maximum amount of physical memory occupied by the process. It includes the model, libraries, and working buffers.

Weights on disk

lower is better

  1. Original FP322.342 GB
  2. FP161.171 GB
  3. INT60.573 GB
  4. INT40.447 GB

Resident memory

peak RSS for the full process, lower is better

  1. Original5.059 GB
  2. FP161.350 GB
  3. INT60.755 GB
  4. INT40.626 GB

Five minutes of audio

after warm-up, lower is better

  1. Original2.79 s
  2. FP161.95 s
  3. INT62.20 s
  4. INT42.56 s
Line length shows each value relative to the original PyTorch/MPS implementation in that column. Blue marks INT8, the default variant.
Variant Mean WER, 4 languages 5 min after warm-up Peak memory (RSS) Weights on disk
Original PyTorch/MPS, FP32 weights 5.046% 2.789 s 5.059 GB 2.342 GB
MLX FP16 5.066% 1.952 s 1.350 GB 1.171 GB
MLX INT8 g64, default 5.070% 2.036 s 0.877 GB 0.699 GB
MLX INT6 g64 5.069% 2.195 s 0.755 GB 0.573 GB
MLX INT4 g64 5.219% 2.563 s 0.626 GB 0.447 GB

Chart and table data: complete benchmark JSON and compact CSV for the five variants.

Speed relative to real time

GigaAM performs ASR, or automatic speech recognition. ASR systems commonly report speed with RTF: processing time divided by audio duration. A lower RTF means a faster model. Its reciprocal shows how many times faster than real time the model runs.

Variant 5 minutes of audio RTF Speed vs real time
Original PyTorch/MPS2.789 s0.0093107.6×
MLX FP161.952 s0.0065153.7×
MLX INT8 g642.036 s0.0068147.3×
MLX INT6 g642.195 s0.0073136.6×
MLX INT4 g642.563 s0.0085117.0×

Speed table data: JSON with complete measurements and CSV with RTF and processing speed.

GPU memory is tracked separately from RSS because the CPU and GPU on Apple Silicon share one unified memory pool.

The table points to three practical choices:

A smaller file does not guarantee higher speed. Packed integer values must be unpacked and converted into a suitable compute format before multiplication. On M4 Pro, this extra work made FP16 slightly faster than INT8, INT6, and INT4. Speed was therefore measured separately for every variant.

The public benchmark report contains the complete methodology, confidence intervals, and per-language results.

Where the time goes

Each stage was timed separately on 20 seconds of audio to find the bottleneck. The recording becomes 1,999 short spectrogram frames. Their count is then reduced to about 500, and the 24 Conformer blocks perform nearly all remaining work. Measurements used the same M4 Pro with MLX 0.32.0. After every stage, mx.eval() forced MLX to finish computation before the timer was read.

Full FP16 pass after warm-up 120.23 ms
  1. WAV 20 seconds of audio
  2. Audio frontend 1,999 log-mel frames 0.28 ms / 0.2%
  3. Sequence 4× shorter 500 × 1024 1.36 ms / 1.1%
  4. Frame position RoPE positional encoding 0.18 ms / 0.1%
  5. Encoder 24 Conformer blocks 118.75 ms / 98.8%
  6. CTC layer character scores 0.21 ms / 0.2%
  7. Decoding text on CPU 0.15 ms / 0.1%
Stages were measured separately, so rounded shares do not have to add up to exactly 100%. The encoder determines nearly all transcription time.

Audio preparation, the CTC output layer, and conversion to text together occupy too little time to provide a large end-to-end gain. The main computation is concentrated inside the 24 identical Conformer blocks.

Time per block 5.49 ms, separate FP16 measurement
3.04 ms 1.40 ms 0.94 ms
Model parameters share of 585.33M parameters
402.9M 100.8M 75.8M
  • FFN3.04 ms, 55.4% of time / 68.8% of parameters
  • Attention1.40 ms, 25.5% of time / 17.2% of parameters
  • Convolution module0.94 ms, 17.1% of time / 12.9% of parameters
  • Other operationsabout 0.11 ms, 2.0% of time / 1.1% of parameters
A separate FP16 measurement puts the complete block at 5.49 ms. FFN means feed-forward network. Each Conformer block contains two FFNs, which together account for more than half of its time.

The profile explains the optimization priorities. Of 585.33 million parameters, about 402.90 million are in the FFNs. Attention projections account for 17.2%, and Conformer convolution modules account for another 12.9%.

The standard attention calculation was replaced with the built-in mx.fast.scaled_dot_product_attention operation. The full pass became 3.8% faster in FP16 and 4.4% faster in INT8. Attention occupies about a quarter of one block’s time, so accelerating only this component produces a gain of several percent for the entire model.

Which optimizations actually made the model faster

Candidates were tested one at a time in separate processes. The published code and weights remained unchanged during the investigation.

  1. Process 16 audio chunks, 8 at a timeFP16, each chunk 20 seconds +10.9%
  2. Increase chunk length to 40 secondsFP16, five-minute audio +8.2%
  3. Accelerate attention with SDPAFP16, full pass +3.8%
  4. Enable mx.compile()INT8, full pass +3.1%
  5. Enable mx.compile()FP16, full pass +0.8%
The scale ends at 12%. Merging the Q and K projections produced less than 1% for the full pass.

In the first measurement, the model received 16 chunks of 20 seconds each. They were processed in two groups of eight. Total time fell from 1.91 to 1.72 seconds, so the model processed 10.9% more audio per unit of time. Per-file latency was not evaluated in this test.

The gains cannot be added arithmetically. They use some of the same resources and alter the shape of the computation graph.

Chunk length must be tuned for each weight variant. FP16 gained 8.2% when the chunk grew from 20 to 40 seconds. INT8 lost 10.2% with the same shape. Processing eight chunks at once accelerated FP16 by 10.9% and slowed INT8 by 1.9%. One shared setting would have made the default variant worse.

Tests of mx.compile() showed that the effect depends on input size. Compilation produced +0.8% for FP16 and +3.1% for INT8. The arbitrary-input-size mode (shapeless=True) reached a technical limitation in mx.as_strided during audio preparation.

Why parts of the model cannot simply be removed

Temporarily disabling or replacing part of a model is called an ablation. The experiment reveals how that component contributes to speed and quality. For example, the simpler ReLU function barely accelerated a complete feed-forward block: 1.51 ms instead of 1.52 ms with SiLU. Most time is spent multiplying large matrices, so replacing one small operation changes very little.

Diagnostic ablations were then run on 100 public FLEURS samples without saving new weights. The original configuration had a WER of 6.51% on this subset.

  1. Original configuration24 layers 1.00×WER 6.51%
  2. SiLU replaced with ReLUquality collapsed 1.00×WER 99.23%
  3. First FFN removedin every layer 1.26×WER 52.03%
  4. Convolution module removedempty outputs 1.12×WER 100%
  5. First 20 layers retained4 layers removed 1.11×WER 99.62%
  6. Every second layer retained12 layers 1.50×WER 147.20%
  7. Frame count reduced by 8×training required 1.48×WER 46.36%
Dot position shows speedup on a common scale. The number on the right is the resulting WER. Every accelerated variant failed the quality criterion.

WER can exceed 100% when a model inserts many extra words. These tests used existing weights after a mechanical change to the model. Every accelerated variant severely degraded recognition.

Even replacing the activation function changed the signals flowing between layers. Removing half of the blocks accelerated computation by 1.50×, while recognition stopped working. Changes of this scale require retraining or distilling knowledge from the large model into a smaller one.

The limit of acceleration without training

Working optimizations

+4.4%built-in SDPA, INT8
+8.2%40-second chunks, FP16
+10.9%8 chunks at once, FP16

Diagnostic ablations

  1. 1.26×first FFN removed, WER 52.03%
  2. 1.48×8× time compression, WER 46.36%
  3. 1.50×every second layer retained, WER 147.20%
Working optimizations preserved quality. Larger gains in the ablations came with a sharp increase in WER.

Optimizations without training produced gains from +0.8% to +10.9%, depending on the mode. Removing model components reached 1.50×, while recognition quality fell sharply. Only variants that preserved quality were included in the final results.

The workflow

The work was divided into three consecutive tracks:

  1. Preserve behavior Pin the code revision, preprocessing, and decoding. Compare intermediate tensors. Confirm FP32 and FP16 equivalence.
  2. Measure the result Evaluate every variant on the same quality suite. Measure file size, loading, latency, peak RSS, and Metal memory separately. Locate the main bottleneck.
  3. Verify and publish Test optimizations on complete inputs. Publish sample lists, versions, checksums, commands, and limitations.
The workflow connects implementation, quality verification, measurement, and published artifacts.

The finished result is available on GitHub, PyPI, and in a Hugging Face Collection. INT8 g64 is the default. FP16 provides the lowest measured latency, while INT4 provides the smallest size and memory footprint.

This text was prepared by the Codex AI agent from materials produced during the working session.

Reproducibility

  1. Original GigaAMmodel and code
  2. GitHubMLX implementation and commands
  3. PyPIinstallable package
  4. Hugging Facefour weight variants
  5. Public benchmarksample lists, versions, and report
Every published number is tied to code, a specific weight revision, and a pinned set of inputs.

Every published benchmark input is publicly available. Private recordings, model weights, datasets, caches, and large raw results are not stored in the GitHub repository.