Download SpeechKit/Sources/ASRKit/AssetStore.swift from Edge0/Audio8-ASR-0.1B-iOS-ANE: direct link, hf CLI and curl.
- Browser
- Download file 3.38 kB
-
https://huggingface.co/Edge0/Audio8-ASR-0.1B-iOS-ANE/resolve/main/SpeechKit/Sources/ASRKit/AssetStore.swift
- Command line
-
hf download hf://Edge0/Audio8-ASR-0.1B-iOS-ANE/SpeechKit/Sources/ASRKit/AssetStore.swift
-
curl -L -o AssetStore.swift https://huggingface.co/Edge0/Audio8-ASR-0.1B-iOS-ANE/resolve/main/SpeechKit/Sources/ASRKit/AssetStore.swift
3.38 kB
| import Foundation | |
| import SpeechCore | |
| /// Loads decoded model assets (mel filters, projector weights, embedding | |
| /// table, vocab decode table) from a verified AssetBundle. | |
| /// Internal to the SDK; integrators only see ASRTranscriber. | |
| package final class AssetStore { | |
| package struct Manifest: Codable { | |
| package struct PromptIDs: Codable { | |
| package let user: Int | |
| package let bos_audio: Int | |
| package let audio: Int | |
| package let eos_audio: Int | |
| package let text: [Int] | |
| package let assistant: Int | |
| } | |
| package struct Tokens: Codable { | |
| package let audio_token_id: Int | |
| package let pad_token_id: Int | |
| package let eos_token_ids: [Int] | |
| package let extra_block_token_ids: [Int] | |
| } | |
| package let prompt_ids: PromptIDs | |
| package let tokens: Tokens | |
| } | |
| package let manifest: Manifest | |
| package let hannWindow: [Float] | |
| package let melFilters: [Float] | |
| package let projNormW: [Float] | |
| package let projNormB: [Float] | |
| package let projLinW: [Float] // 512*1024 row-major [out][in] | |
| package let projLinB: [Float] | |
| private let embeddingData: Data // fp16, vocab*512 | |
| private let vocabBytes: Data | |
| private let vocabOffsets: [UInt32] | |
| package let embeddingDim = 512 | |
| package init(bundle: AssetBundle) throws { | |
| func data(_ name: String) throws -> Data { | |
| try Data(contentsOf: bundle.url(name), options: .mappedIfSafe) | |
| } | |
| func floats(_ name: String) throws -> [Float] { | |
| try data(name).withUnsafeBytes { Array($0.bindMemory(to: Float.self)) } | |
| } | |
| do { | |
| manifest = try JSONDecoder().decode(Manifest.self, from: data("asr_manifest")) | |
| } catch let e as SpeechError { | |
| throw e | |
| } catch { | |
| throw SpeechError.assetMissing("asr_manifest (decode: \(error.localizedDescription))") | |
| } | |
| hannWindow = try floats("hann_window") | |
| melFilters = try floats("mel_filters") | |
| projNormW = try floats("projector_norm_w") | |
| projNormB = try floats("projector_norm_b") | |
| projLinW = try floats("projector_lin_w") | |
| projLinB = try floats("projector_lin_b") | |
| embeddingData = try data("token_embedding") | |
| vocabBytes = try data("vocab_bytes") | |
| vocabOffsets = try data("vocab_offsets").withUnsafeBytes { | |
| Array($0.bindMemory(to: UInt32.self)) | |
| } | |
| } | |
| /// fp16 -> fp32 embedding row lookup | |
| package func embedding(for tokenID: Int) -> [Float] { | |
| let rowBytes = embeddingDim * MemoryLayout<Float16>.size | |
| let start = tokenID * rowBytes | |
| return embeddingData.subdata(in: start..<(start + rowBytes)).withUnsafeBytes { | |
| $0.bindMemory(to: Float16.self).map { Float($0) } | |
| } | |
| } | |
| package func decode(_ tokenIDs: [Int]) -> String { | |
| var bytes = Data() | |
| for id in tokenIDs where id >= 0 && id + 1 < vocabOffsets.count { | |
| let a = Int(vocabOffsets[id]), b = Int(vocabOffsets[id + 1]) | |
| bytes.append(vocabBytes.subdata(in: a..<b)) | |
| } | |
| let raw = String(decoding: bytes, as: UTF8.self) | |
| return raw.trimmingCharacters(in: .whitespacesAndNewlines) | |
| .replacingOccurrences(of: #"\s+"#, with: " ", options: .regularExpression) | |
| } | |
| } | |