Automatic Speech Recognition
Transformers
Safetensors
PyTorch
arkasr
text-generation
speech
audio
multilingual
hotword
audio8
custom_code
Eval Results
Instructions to use Audio8/Audio8-ASR-0.1B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Audio8/Audio8-ASR-0.1B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("automatic-speech-recognition", model="Audio8/Audio8-ASR-0.1B", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Audio8/Audio8-ASR-0.1B", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
| from __future__ import annotations | |
| import re | |
| from typing import Any, Callable, Dict, List, Sequence, Set | |
| _CONTROL_TOKEN_RE = re.compile(r"<\|[^>]+?\|>") | |
| _BARE_TAG_RE = re.compile(r"</?[^>\s]+>") | |
| _CJK_KANA_HANGUL_RE = re.compile("[\u4e00-\u9fff\u3040-\u30ff\uac00-\ud7af]") | |
| class HotwordTrie: | |
| """Prefix trie over hotword token-id sequences.""" | |
| def __init__( | |
| self, | |
| token_sequences: Sequence[Sequence[int]], | |
| *, | |
| start_boost: float, | |
| continuation_boost: float, | |
| ) -> None: | |
| self.start_boost = float(start_boost) | |
| self.continuation_boost = float(continuation_boost) | |
| self.trie: Dict[int, Dict[int, Any]] = {} | |
| self.max_sequence_len = 0 | |
| for seq in token_sequences: | |
| ids = [int(token_id) for token_id in seq] | |
| if not ids: | |
| continue | |
| node = self.trie | |
| for token_id in ids: | |
| node = node.setdefault(token_id, {}) | |
| self.max_sequence_len = max(self.max_sequence_len, len(ids)) | |
| self.start_token_ids = sorted(self.trie.keys()) | |
| def __bool__(self) -> bool: | |
| return bool(self.trie) | |
| def boosts_for_generated(self, generated_ids: Sequence[int]) -> Dict[int, float]: | |
| boosts: Dict[int, float] = {} | |
| if self.start_boost: | |
| for token_id in self.start_token_ids: | |
| boosts[token_id] = max(boosts.get(token_id, 0.0), self.start_boost) | |
| if not generated_ids or not self.continuation_boost or self.max_sequence_len <= 1: | |
| return boosts | |
| max_prefix_len = min(len(generated_ids), self.max_sequence_len - 1) | |
| for prefix_len in range(1, max_prefix_len + 1): | |
| node: Dict[int, Any] = self.trie | |
| matched = True | |
| for token_id in generated_ids[-prefix_len:]: | |
| next_node = node.get(int(token_id)) | |
| if next_node is None: | |
| matched = False | |
| break | |
| node = next_node | |
| if not matched: | |
| continue | |
| for next_token_id in node.keys(): | |
| boosts[int(next_token_id)] = max( | |
| boosts.get(int(next_token_id), 0.0), | |
| self.continuation_boost, | |
| ) | |
| return boosts | |
| def _has_cjk_or_kana_or_hangul(text: str) -> bool: | |
| return bool(_CJK_KANA_HANGUL_RE.search(str(text or ""))) | |
| def _hotword_text_variants(word: str) -> List[str]: | |
| word = str(word or "").strip() | |
| if not word: | |
| return [] | |
| variants = [word] | |
| if not _has_cjk_or_kana_or_hangul(word) and re.search(r"[A-Za-z0-9_]", word): | |
| variants.append(" " + word) | |
| out: List[str] = [] | |
| seen: Set[str] = set() | |
| for value in variants: | |
| if value not in seen: | |
| seen.add(value) | |
| out.append(value) | |
| return out | |
| def token_is_control_or_special(token: str, token_id: int, special_ids: Set[int]) -> bool: | |
| if int(token_id) in special_ids: | |
| return True | |
| token = str(token) | |
| return bool(_CONTROL_TOKEN_RE.fullmatch(token) or _BARE_TAG_RE.fullmatch(token)) | |
| def build_hotword_sequences( | |
| hotwords: Sequence[str], | |
| *, | |
| encode: Callable[[str], List[int]], | |
| id_to_token: Callable[[int], str], | |
| special_ids: Set[int], | |
| ) -> Dict[str, List[List[int]]]: | |
| special_ids = set(int(value) for value in special_ids if value is not None) | |
| sequences: Dict[str, List[List[int]]] = {} | |
| seen_global: Set[tuple[int, ...]] = set() | |
| for word in hotwords: | |
| word = str(word or "").strip() | |
| if not word: | |
| continue | |
| variants: List[List[int]] = [] | |
| for text in _hotword_text_variants(word): | |
| ids = [ | |
| int(token_id) | |
| for token_id in encode(text) | |
| if not token_is_control_or_special(id_to_token(int(token_id)), int(token_id), special_ids) | |
| ] | |
| key = tuple(ids) | |
| if not key or key in seen_global: | |
| continue | |
| seen_global.add(key) | |
| variants.append(ids) | |
| if variants: | |
| sequences[word] = variants | |
| return sequences | |
| def flatten_sequences(sequences_by_word: Dict[str, List[List[int]]]) -> List[List[int]]: | |
| return [ids for variants in sequences_by_word.values() for ids in variants] | |
| def parse_hotwords(raw: Any) -> List[str]: | |
| values: List[str] = [] | |
| if isinstance(raw, (list, tuple)): | |
| values = [str(value).strip() for value in raw] | |
| elif raw: | |
| values = [value.strip() for value in re.split(r"[,,]", str(raw))] | |
| out: List[str] = [] | |
| seen: Set[str] = set() | |
| for value in values: | |
| if value and value not in seen: | |
| seen.add(value) | |
| out.append(value) | |
| return out | |
| def build_trie_from_hotwords( | |
| hotwords: Sequence[str], | |
| *, | |
| encode: Callable[[str], List[int]], | |
| id_to_token: Callable[[int], str], | |
| special_ids: Set[int], | |
| start_boost: float, | |
| continuation_boost: float, | |
| ) -> tuple[HotwordTrie, Dict[str, List[List[int]]]]: | |
| sequences_by_word = build_hotword_sequences( | |
| hotwords, | |
| encode=encode, | |
| id_to_token=id_to_token, | |
| special_ids=special_ids, | |
| ) | |
| trie = HotwordTrie( | |
| flatten_sequences(sequences_by_word), | |
| start_boost=start_boost, | |
| continuation_boost=continuation_boost, | |
| ) | |
| return trie, sequences_by_word | |