Automatic Speech Recognition
MLX
ONNX
GGUF
Rust
English
Chinese
audio8
streaming-asr
quantized
experimental
Instructions to use Reza2kn/Audio8-ASR-Infinite-Compressed with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use Reza2kn/Audio8-ASR-Infinite-Compressed with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download Reza2kn/Audio8-ASR-Infinite-Compressed --local-dir Audio8-ASR-Infinite-Compressed
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
File size: 8,043 Bytes
21fd722 | 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 104 105 106 107 108 109 110 111 112 113 | """Live speech-gated MLX captions using actual causal CPU VAD decisions."""
import hashlib
import json
from pathlib import Path
import struct
import sys
import time
import mlx.core as mx
from .silero_input import GatedPCM,Silero,MODEL_SHA256,POLICY
from .stream import TextDecoder,require
from .weights import sha256
def run(args,model,frontend,profile,load_start,warmup_seconds,warmup_calls):
from .cli import emit,memory
import importlib.metadata
vad=Silero(args.silero_vad)
# Prepared before Ready, as in the ordinary CLI. Future segment resets are
# included in the audio clock and measured separately from model windows.
session=model.session(delay_tokens=3)
tokenizer=TextDecoder(args.tokenizer)
mx.synchronize()
stream=sys.stdin.buffer if args.input=='-' else open(args.input,'rb')
emit('caption_stream_ready',backend='mlx_metal',mlx=importlib.metadata.version('mlx'),
weights=model.weights.provenance,weight_resident_bytes=model.weights.nbytes,
config_sha256=sha256(args.config),frontend=frontend.provenance,tokenizer_sha256=tokenizer.table_sha256,
source_sha256={p.name:sha256(p) for p in sorted(Path(__file__).parent.glob('*.py'))},
silero_sha256=MODEL_SHA256,silero_runtime='onnxruntime_cpu',silero_runtime_version=vad.version,silence_policy=POLICY,
startup='realtime18',delay_ms=240,batch=args.batch_windows,first_batch=1,dtype=args.dtype,cache_dtype=args.cache_dtype,
math_mode=args.math_mode,fuse_projections=args.fuse_projections,projection_warmup_seconds=warmup_seconds,
projection_warmup_calls=warmup_calls,input_mode='stdin' if args.input=='-' else ('paced_file' if args.pace_audio else 'unpaced_file'),
load_seconds=time.monotonic()-load_start,memory=memory(),production_accuracy_approved=False)
started=time.monotonic();source=GatedPCM(stream,vad.probability,started if args.pace_audio else None)
ids=hashlib.sha256();emissions=0;total_work=total_reset=0.;text_bytes=0;peak_cache=0
prior_visible=segment_visible=False;active=None;local_index=0;previous=None
def text_event(delta,segment,**fields):
nonlocal prior_visible,segment_visible,text_bytes
if not delta:return
seconds=time.monotonic()-started
if not segment_visible and prior_visible:
emit('caption_text_delta',segment=segment,index=emissions,seconds=seconds,text='\n',segment_separator=True)
text_bytes+=1
segment_visible=prior_visible=True;text_bytes+=len(delta.encode('utf8'))
emit('caption_text_delta',segment=segment,index=emissions,seconds=seconds,text=delta,**fields)
try:
events=iter(source);pending=None
while True:
event=pending if pending is not None else next(events)
pending=None
if event['kind']=='start':
s=event['segment'];require(active is None,'overlapping MLX caption session')
active=s['id'];local_index=0;previous=None;segment_visible=False
began=time.monotonic()
if active:
session=None;mx.clear_cache();session=model.session(delay_tokens=3)
tokenizer=tokenizer.fresh()
reset=time.monotonic()-began;total_reset+=reset
require(session.position==0 and all(c.length==0 for c in session.encoder+session.decoder),'fresh MLX caches')
emit('caption_segment_start',segment=active,start_sample=s['start_sample'],decision_sample=s['decision_sample'],
seconds=time.monotonic()-started,reset_seconds=reset)
elif event['kind']=='window':
require(active==event['segment']['id'] and local_index==event['index'],'MLX caption source clock')
inputs=profile.prompt() if local_index==0 else [previous]
capacity=session.batch_capacity(1 if local_index==0 else args.batch_windows,len(inputs))
group=[event]
while len(group)<capacity:
following=next(events)
if following['kind']!='window':
pending=following;break
require(following['segment']['id']==active and following['index']==local_index+len(group),'batch crosses segment')
group.append(following)
began=time.monotonic();available=max(w['available_sample'] for w in group);ready=available/16000
queue=max(0.,began-started-ready) if args.pace_audio or args.input=='-' else None
first_local=local_index;first_global=emissions;last_callback=began
def token_ready(offset,token):
nonlocal previous,peak_cache,emissions,local_index,last_callback
require(type(token) is int and 0<=token<tokenizer.model_count and token!=151645,'MLX greedy token contract')
require(offset==local_index-first_local and emissions==first_global+offset,'MLX batch callback clock')
require(session.position+session.trims*38==18+local_index,'MLX absolute position differs')
now=time.monotonic();interval=now-last_callback;last_callback=now
previous=token;ids.update(struct.pack('<I',token));peak_cache=max(peak_cache,session.cache_bytes)
text_event(tokenizer.push(token),active)
w=group[offset]
emit('caption_window',index=emissions,segment=active,segment_index=local_index,token_id=token,
seconds=time.monotonic()-started,source_dependency_sample=w['nominal_source_end_sample'],
available_source_sample=available,eof_drain=w['nominal_source_end_sample']>available,queue_seconds=queue,
work_seconds=interval,cache_bytes=session.cache_bytes,rolling_trims=session.trims,
batch_first_index=first_global,batch_windows=len(group),batch_offset=offset)
emissions+=1;local_index+=1
session.step_batch([w['audio'] for w in group],inputs,on_token=token_ready)
require(local_index-first_local==len(group),'MLX missing batch callback')
total_work+=time.monotonic()-began
elif event['kind']=='end':
require(active==event['segment']['id'] and local_index==event['windows'],'MLX caption end clock')
text_event(tokenizer.finish(),active,utf8_final_flush=True)
emit('caption_segment_end',segment=active,start_sample=event['segment']['start_sample'],
end_sample=event['end_sample'],final_eof=event['final_eof'],unconsumed_samples=event['unconsumed_samples'],
windows=local_index,seconds=time.monotonic()-started)
active=None
elif event['kind']=='complete':break
require(active is None and source.reader.eof,'MLX caption incomplete EOF')
audio_seconds=source.reader.samples/16000
emit('caption_stream_complete',status='complete',audio_samples=source.reader.samples,audio_seconds=audio_seconds,
segments=source.segment_count,selected_samples=source.selected_samples,unconsumed_selected_samples=source.unconsumed_samples,
emissions=emissions,text_bytes=text_bytes,model_seconds=total_work,reset_seconds=total_reset,vad_seconds=source.vad_seconds,
read_seconds=source.read_seconds,sleep_seconds=source.sleep_seconds,elapsed_seconds=time.monotonic()-started,
work_rtf=(total_work+total_reset+source.vad_seconds)/audio_seconds if audio_seconds else None,
peak_cache_bytes=peak_cache,max_retained_input_samples=source.reader.max_retained_samples,
input_sha256=source.reader.digest.hexdigest(),generated_ids_sha256=ids.hexdigest(),memory=memory(),
all_source_audio_observed=True,measured_word_aligned_latency=False,production_accuracy_approved=False)
finally:
if args.input!='-':stream.close()
|