#!/usr/bin/env python3 from __future__ import annotations import argparse from pathlib import Path import torch from transformers import AutoModelForCausalLM, AutoProcessor PROMPT = "Please transcribe this audio." def build_conversation(audio_path: Path) -> list[dict]: return [ { "role": "user", "content": [ {"type": "audio", "path": str(audio_path)}, {"type": "text", "text": PROMPT}, ], } ] def main() -> None: parser = argparse.ArgumentParser(description="Transcribe one audio file with audio8-asr-0.1B.") parser.add_argument("audio", type=Path) parser.add_argument("--model", default=".") parser.add_argument("--device", default="cuda" if torch.cuda.is_available() else "cpu") parser.add_argument("--max_new_tokens", type=int, default=128) parser.add_argument("--max_audio_seconds", type=int, default=30) args = parser.parse_args() device = torch.device(args.device) dtype = torch.bfloat16 if device.type == "cuda" else torch.float32 processor = AutoProcessor.from_pretrained(args.model, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( args.model, trust_remote_code=True, torch_dtype=dtype, attn_implementation="eager", ).to(device) model.eval() batch = processor.apply_chat_template( build_conversation(args.audio), return_tensors="pt", sampling_rate=16000, audio_padding="longest", add_generation_prompt=True, audio_max_length=int(args.max_audio_seconds) * 16000, text_kwargs={"padding": "longest", "truncation": True, "max_length": 1000}, ) batch = {key: value.to(device) if hasattr(value, "to") else value for key, value in dict(batch).items()} with torch.inference_mode(): output_ids = model.generate(**batch, max_new_tokens=args.max_new_tokens, do_sample=False) prompt_len = int(batch["input_ids"].shape[1]) text = processor.decode(output_ids[0, prompt_len:], skip_special_tokens=True).strip() print(text) if __name__ == "__main__": main()