Skip to content

Commit 43274ac

Browse files
committed
Add experimental ARK-ASR 0.6B transcription support
1 parent 255f12f commit 43274ac

6 files changed

Lines changed: 131 additions & 9 deletions

File tree

‎Cargo.lock‎

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ serde_json = "1.0.151"
4040
sha2 = "0.11.0"
4141
tracing = "0.1.44"
4242
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
43-
transcribe-cpp = "=0.2.4"
43+
transcribe-cpp = { git = "https://github.com/maxffarrell/transcribe.cpp", rev = "19f301609c06126e5071d1de5acdd95c714eec05" }
4444
transcribe-rs = { git = "https://github.com/cjpais/transcribe-rs", rev = "e37c66b6df43af51fde8dec34f98a07aaf09564c", features = ["onnx"], optional = true }
4545
unicode-segmentation = "1.13.3"
4646
url = "2.5.8"
@@ -75,7 +75,7 @@ evdev = "0.13.2"
7575
gpui = { version = "0.2.2", default-features = false, features = ["font-kit", "wayland", "x11"] }
7676
gtk = "0.18.2"
7777
gtk-layer-shell = { version = "0.8.2", features = ["v0_6"] }
78-
transcribe-cpp = { version = "=0.2.4", features = ["vulkan"] }
78+
transcribe-cpp = { git = "https://github.com/maxffarrell/transcribe.cpp", rev = "19f301609c06126e5071d1de5acdd95c714eec05", features = ["vulkan"] }
7979
udev = "0.9.3"
8080
x11-clipboard = "0.9.3"
8181
x11rb = { version = "0.14.0", features = ["xtest"] }

‎docs/features/README.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,39 @@ Permissions revoked later
9999
Apple silicon, macOS 15+. Choices come from the compiled model/language catalog;
100100
Apple Speech is currently excluded from the desktop picker.
101101

102+
ARK-ASR 0.6B is an experimental alternative in Auto and its 19 published
103+
language groups, with the stable CLI/service/SDK ID `ark_asr06_b`. Selection
104+
uses automatic language detection; choosing a language filters availability
105+
but does not force ARK's output language. Recognition hints and timestamps are
106+
unavailable. Existing defaults and ranked recommendations are preserved.
107+
The candidate requires the pinned ARK-enabled transcribe.cpp fork in
108+
`Cargo.toml`; upstream acceptance is tracked in
109+
[transcribe.cpp #190](https://github.com/handy-computer/transcribe.cpp/issues/190)
110+
and [draft #191](https://github.com/handy-computer/transcribe.cpp/pull/191).
111+
The converted artifact is pinned by revision, exact size, SHA-256 and
112+
`arkasr/ark-asr-0.6b` identity in the catalog, so ordinary preparation,
113+
cancellation and transactional warm activation apply.
114+
115+
The candidate's six public short samples match the original model across
116+
F16 and Q8, but include original-model failures: a Korean sample produces
117+
Japanese and nonspeech produces text. The upstream LibriSpeech number shown
118+
in the picker is publisher-reported, not a local GGUF WER result. The
119+
`ark_choices_use_detection_without_claiming_language_steering` regression
120+
covers availability, unsupported languages and hints. Native download,
121+
installed-app UI, physical microphone/paste and Linux inference require
122+
separate evidence; reference comparisons do not establish those flows.
123+
124+
Executed October 4 candidate verification: 495 Rust tests passed (12 opt-in
125+
tests ignored), all twelve keyboard-layout child scenarios passed, strict
126+
all-target/all-feature Clippy and formatting passed, and the public SDK passed
127+
70 tests, typecheck and build. In an isolated Application Support directory,
128+
the headless Hex service downloaded and verified the pinned ARK artifact,
129+
completed warm activation, returned the reference JFK text for both Auto and
130+
English selections, rejected Russian preparation with HTTP 400, and removed
131+
its discovery file on clean shutdown. This verifies model preparation and
132+
service transcription; installed-app UI, physical microphone/paste and Linux
133+
inference remain unverified.
134+
102135
```ts
103136
Choose a supported language // setup.language-conditioning; macOS + Linux picker
104137
├── Parakeet v3 -> Detect language from audio; selected language does not constrain output

‎sdk/.changeset/ark-asr-model.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@kitlangton/hex": patch
3+
---
4+
5+
Accept the ARK-ASR 0.6B model identifier in the transcription protocol.

‎sdk/typescript/src/types.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const MODEL_IDS = [
44
"parakeet_v3",
55
"whisper_large_v3_turbo",
66
"qwen3_asr06_b",
7+
"ark_asr06_b",
78
"sense_voice_small",
89
"cohere_transcribe",
910
"apple_speech",

‎src/transcription_models.rs‎

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub enum TranscriptionModelId {
2222
ParakeetV3,
2323
WhisperLargeV3Turbo,
2424
Qwen3Asr06B,
25+
ArkAsr06B,
2526
SenseVoiceSmall,
2627
CohereTranscribe,
2728
AppleSpeech,
@@ -35,6 +36,7 @@ impl TranscriptionModelId {
3536
Self::ParakeetV3 => "parakeet_v3",
3637
Self::WhisperLargeV3Turbo => "whisper_large_v3_turbo",
3738
Self::Qwen3Asr06B => "qwen3_asr06_b",
39+
Self::ArkAsr06B => "ark_asr06_b",
3840
Self::SenseVoiceSmall => "sense_voice_small",
3941
Self::CohereTranscribe => "cohere_transcribe",
4042
Self::AppleSpeech => "apple_speech",
@@ -52,6 +54,7 @@ impl FromStr for TranscriptionModelId {
5254
"parakeet_v3" => Ok(Self::ParakeetV3),
5355
"whisper_large_v3_turbo" => Ok(Self::WhisperLargeV3Turbo),
5456
"qwen3_asr06_b" => Ok(Self::Qwen3Asr06B),
57+
"ark_asr06_b" => Ok(Self::ArkAsr06B),
5558
"sense_voice_small" => Ok(Self::SenseVoiceSmall),
5659
"cohere_transcribe" => Ok(Self::CohereTranscribe),
5760
"apple_speech" => Ok(Self::AppleSpeech),
@@ -110,6 +113,7 @@ impl Default for TranscriptionSelection {
110113

111114
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
112115
pub enum Recommendation {
116+
Alternative,
113117
Recommended,
114118
Fastest,
115119
MostAccurate,
@@ -119,6 +123,7 @@ pub enum Recommendation {
119123
impl Recommendation {
120124
pub const fn label(self) -> &'static str {
121125
match self {
126+
Self::Alternative => "Alternative",
122127
Self::Recommended => "Recommended",
123128
Self::Fastest => "Fastest",
124129
Self::MostAccurate => "Most accurate",
@@ -303,6 +308,20 @@ const COHERE_ARTIFACT: GgufArtifact = GgufArtifact {
303308
variant: "cohere-transcribe-03-2026",
304309
};
305310

311+
const ARK_LANGUAGES: &[&str] = &[
312+
"zh", "en", "de", "ja", "fr", "ko", "es", "pl", "it", "ro", "hu", "cs", "nl", "fi", "hr", "sk",
313+
"sl", "et", "lt",
314+
];
315+
const ARK_ARTIFACT: GgufArtifact = GgufArtifact {
316+
filename: "ark-asr-0.6b-Q8_0.gguf",
317+
revision: "aa2af66f16bb8f04c2da550ce07880e0c3a7e7d4",
318+
repository: "maxffarrell/ARK-ASR-0.6B-GGUF",
319+
bytes: 1_372_881_664,
320+
sha256: "ceca6bacd9cab3b52892de6703562aeeb62dc8a4b14aab0b020706637dd127dc",
321+
architecture: "arkasr",
322+
variant: "ark-asr-0.6b",
323+
};
324+
306325
pub const MODELS: &[ModelDefinition] = &[
307326
ModelDefinition {
308327
id: TranscriptionModelId::ParakeetUnifiedEnglish,
@@ -380,6 +399,21 @@ pub const MODELS: &[ModelDefinition] = &[
380399
supports_language_detection: true,
381400
supports_recognition_hints: false,
382401
},
402+
ModelDefinition {
403+
id: TranscriptionModelId::ArkAsr06B,
404+
name: "ARK-ASR 0.6B",
405+
realtime: "Unmeasured",
406+
realtime_context: "no dictation benchmark",
407+
quality: "1.87%",
408+
quality_context: "upstream LibriSpeech clean WER",
409+
coverage: "19 languages · automatic detection",
410+
timestamps: "No timestamps",
411+
runtime: ModelRuntime::Gguf(&ARK_ARTIFACT),
412+
languages: ARK_LANGUAGES,
413+
accepts_language_hint: false,
414+
supports_language_detection: true,
415+
supports_recognition_hints: false,
416+
},
383417
ModelDefinition {
384418
id: TranscriptionModelId::SenseVoiceSmall,
385419
name: "SenseVoice Small",
@@ -491,7 +525,7 @@ pub(crate) fn choices_for_runtime(language: &str) -> Vec<ModelChoice> {
491525
model: definition(id),
492526
recommendation,
493527
};
494-
match language {
528+
let mut choices = match language {
495529
AUTO_LANGUAGE => vec![
496530
choice(
497531
TranscriptionModelId::WhisperLargeV3Turbo,
@@ -558,7 +592,14 @@ pub(crate) fn choices_for_runtime(language: &str) -> Vec<ModelChoice> {
558592
TranscriptionModelId::WhisperLargeV3Turbo,
559593
Recommendation::Recommended,
560594
)],
595+
};
596+
if definition(TranscriptionModelId::ArkAsr06B).supports_language(language) {
597+
choices.push(choice(
598+
TranscriptionModelId::ArkAsr06B,
599+
Recommendation::Alternative,
600+
));
561601
}
602+
choices
562603
}
563604

564605
pub fn validate(selection: &TranscriptionSelection) -> Result<&'static ModelDefinition> {
@@ -1025,6 +1066,7 @@ mod tests {
10251066
"whisper_large_v3_turbo",
10261067
),
10271068
(TranscriptionModelId::Qwen3Asr06B, "qwen3_asr06_b"),
1069+
(TranscriptionModelId::ArkAsr06B, "ark_asr06_b"),
10281070
(TranscriptionModelId::SenseVoiceSmall, "sense_voice_small"),
10291071
(TranscriptionModelId::CohereTranscribe, "cohere_transcribe"),
10301072
(TranscriptionModelId::AppleSpeech, "apple_speech"),
@@ -1036,6 +1078,49 @@ mod tests {
10361078
assert!("unknown".parse::<TranscriptionModelId>().is_err());
10371079
}
10381080

1081+
#[test]
1082+
fn ark_choices_use_detection_without_claiming_language_steering() {
1083+
let ark = definition(TranscriptionModelId::ArkAsr06B);
1084+
for language in ARK_LANGUAGES.iter().copied().chain([AUTO_LANGUAGE]) {
1085+
assert!(
1086+
validate(&TranscriptionSelection {
1087+
model: ark.id,
1088+
language: language.into(),
1089+
recognition_hints: String::new(),
1090+
})
1091+
.is_ok()
1092+
);
1093+
assert_eq!(ark.runtime_language_hint(language), None);
1094+
assert_eq!(
1095+
choices_for_runtime(language).last().unwrap().model.id,
1096+
ark.id
1097+
);
1098+
}
1099+
for language in ["yue", "pt", "ru", "ar"] {
1100+
assert!(
1101+
validate(&TranscriptionSelection {
1102+
model: ark.id,
1103+
language: language.into(),
1104+
recognition_hints: String::new(),
1105+
})
1106+
.is_err()
1107+
);
1108+
assert!(
1109+
choices_for_runtime(language)
1110+
.iter()
1111+
.all(|choice| choice.model.id != ark.id)
1112+
);
1113+
}
1114+
assert!(
1115+
validate(&TranscriptionSelection {
1116+
model: ark.id,
1117+
language: AUTO_LANGUAGE.into(),
1118+
recognition_hints: "preferred spelling".into(),
1119+
})
1120+
.is_err()
1121+
);
1122+
}
1123+
10391124
#[test]
10401125
fn apple_speech_is_retained_only_for_persisted_selection_migration() {
10411126
assert!(

0 commit comments

Comments
 (0)