Sync from GitHub f50c848
Browse files- app.py +24 -1
- frontend/index.html +12 -12
- frontend/vendor/moonshine-tiny-ONNX/config.json +34 -0
- frontend/vendor/moonshine-tiny-ONNX/generation_config.json +7 -0
- frontend/vendor/moonshine-tiny-ONNX/onnx/decoder_model_merged_quantized.onnx +3 -0
- frontend/vendor/moonshine-tiny-ONNX/onnx/encoder_model_quantized.onnx +3 -0
- frontend/vendor/moonshine-tiny-ONNX/preprocessor_config.json +5 -0
- frontend/vendor/moonshine-tiny-ONNX/special_tokens_map.json +1 -0
- frontend/vendor/moonshine-tiny-ONNX/tokenizer.json +0 -0
- frontend/vendor/moonshine-tiny-ONNX/tokenizer_config.json +0 -0
app.py
CHANGED
|
@@ -53,7 +53,7 @@ import warnings
|
|
| 53 |
|
| 54 |
import gradio as gr
|
| 55 |
from fastapi.responses import FileResponse, HTMLResponse, Response
|
| 56 |
-
from huggingface_hub import snapshot_download
|
| 57 |
|
| 58 |
from core.constants import (
|
| 59 |
DEFAULT_TOP_K,
|
|
@@ -127,6 +127,9 @@ def sync_library() -> None:
|
|
| 127 |
snapshot_download(
|
| 128 |
LIBRARY_DATASET_ID, repo_type="dataset", local_dir=PREINDEXED_DIR
|
| 129 |
)
|
|
|
|
|
|
|
|
|
|
| 130 |
log.info("library synced from %s", LIBRARY_DATASET_ID)
|
| 131 |
except Exception as e:
|
| 132 |
log.warning("library dataset not synced (%s): %s", LIBRARY_DATASET_ID, e)
|
|
@@ -141,6 +144,25 @@ def sync_library() -> None:
|
|
| 141 |
if os.path.isdir(path) and os.path.isfile(os.path.join(path, "index.json")):
|
| 142 |
print(f"Pruning stale pre-migration doc dir: {entry}")
|
| 143 |
shutil.rmtree(path, ignore_errors=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
|
| 146 |
sync_library()
|
|
@@ -381,6 +403,7 @@ _VENDOR_MEDIA_TYPES = {
|
|
| 381 |
".mjs": "text/javascript",
|
| 382 |
".wasm": "application/wasm",
|
| 383 |
".onnx": "application/octet-stream",
|
|
|
|
| 384 |
}
|
| 385 |
|
| 386 |
|
|
|
|
| 53 |
|
| 54 |
import gradio as gr
|
| 55 |
from fastapi.responses import FileResponse, HTMLResponse, Response
|
| 56 |
+
from huggingface_hub import HfApi, snapshot_download
|
| 57 |
|
| 58 |
from core.constants import (
|
| 59 |
DEFAULT_TOP_K,
|
|
|
|
| 127 |
snapshot_download(
|
| 128 |
LIBRARY_DATASET_ID, repo_type="dataset", local_dir=PREINDEXED_DIR
|
| 129 |
)
|
| 130 |
+
remote_files = HfApi().list_repo_files(
|
| 131 |
+
LIBRARY_DATASET_ID, repo_type="dataset"
|
| 132 |
+
)
|
| 133 |
log.info("library synced from %s", LIBRARY_DATASET_ID)
|
| 134 |
except Exception as e:
|
| 135 |
log.warning("library dataset not synced (%s): %s", LIBRARY_DATASET_ID, e)
|
|
|
|
| 144 |
if os.path.isdir(path) and os.path.isfile(os.path.join(path, "index.json")):
|
| 145 |
print(f"Pruning stale pre-migration doc dir: {entry}")
|
| 146 |
shutil.rmtree(path, ignore_errors=True)
|
| 147 |
+
# snapshot_download only adds/updates; it never removes a local doc dir that
|
| 148 |
+
# was deleted from the dataset. Prune any method/doc dir absent remotely so
|
| 149 |
+
# deletions in the library propagate to the Space on the next sync.
|
| 150 |
+
remote_docs = {
|
| 151 |
+
(parts[0], parts[1])
|
| 152 |
+
for f in remote_files
|
| 153 |
+
if len(parts := f.split("/")) >= 3 and parts[0] in (VISUAL_SUBDIR, PARSED_SUBDIR)
|
| 154 |
+
}
|
| 155 |
+
for method in (VISUAL_SUBDIR, PARSED_SUBDIR):
|
| 156 |
+
method_dir = os.path.join(PREINDEXED_DIR, method)
|
| 157 |
+
if not os.path.isdir(method_dir):
|
| 158 |
+
continue
|
| 159 |
+
for doc_id in os.listdir(method_dir):
|
| 160 |
+
doc_dir = os.path.join(method_dir, doc_id)
|
| 161 |
+
if doc_id.startswith(".") or not os.path.isdir(doc_dir):
|
| 162 |
+
continue
|
| 163 |
+
if (method, doc_id) not in remote_docs:
|
| 164 |
+
print(f"Pruning doc removed from library: {method}/{doc_id}")
|
| 165 |
+
shutil.rmtree(doc_dir, ignore_errors=True)
|
| 166 |
|
| 167 |
|
| 168 |
sync_library()
|
|
|
|
| 403 |
".mjs": "text/javascript",
|
| 404 |
".wasm": "application/wasm",
|
| 405 |
".onnx": "application/octet-stream",
|
| 406 |
+
".json": "application/json", # Moonshine config/tokenizer (self-hosted ASR)
|
| 407 |
}
|
| 408 |
|
| 409 |
|
frontend/index.html
CHANGED
|
@@ -763,20 +763,20 @@ function repairGuy() {
|
|
| 763 |
window.ort.env.wasm.wasmPaths = '/vendor/onnx/';
|
| 764 |
await this.loadScript('/vendor/vad/bundle.min.js');
|
| 765 |
|
| 766 |
-
// 2) Moonshine ASR
|
| 767 |
-
//
|
| 768 |
-
//
|
| 769 |
-
// dtype MUST be a single string, NOT a per-module object: it's applied
|
| 770 |
-
// to every session unconditionally. v4's default for this model picks
|
| 771 |
// the 4-bit (q4) merged decoder, whose MatMulNBits export is malformed
|
| 772 |
// for onnxruntime-web and dies at session creation ("Missing required
|
| 773 |
-
// scale … embed_tokens")
|
| 774 |
-
//
|
| 775 |
-
//
|
| 776 |
-
//
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
|
|
|
|
|
|
| 780 |
|
| 781 |
// 3) the mic: Silero VAD segments speech; onSpeechEnd is our send trigger
|
| 782 |
this.vad = await window.vad.MicVAD.new({
|
|
|
|
| 763 |
window.ort.env.wasm.wasmPaths = '/vendor/onnx/';
|
| 764 |
await this.loadScript('/vendor/vad/bundle.min.js');
|
| 765 |
|
| 766 |
+
// 2) Moonshine ASR — transformers.js library from CDN (pinned), but the
|
| 767 |
+
// MODEL is SELF-HOSTED under /vendor/moonshine-tiny-ONNX/ and remote
|
| 768 |
+
// fetching is OFF. This is deliberate: left to the hub, v4 defaults to
|
|
|
|
|
|
|
| 769 |
// the 4-bit (q4) merged decoder, whose MatMulNBits export is malformed
|
| 770 |
// for onnxruntime-web and dies at session creation ("Missing required
|
| 771 |
+
// scale … embed_tokens") — and that bad file then sticks in the browser
|
| 772 |
+
// cache. We ship ONLY the q8 files (verified MatMulNBits-free), so there
|
| 773 |
+
// is no q4 to pick, no hub round-trip, and no cached-q4 ghost. dtype is
|
| 774 |
+
// a single string (applied to every session); device defaults to wasm.
|
| 775 |
+
const { pipeline, env } = await import('https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0');
|
| 776 |
+
env.allowRemoteModels = false; // never touch the hub — local files only
|
| 777 |
+
env.allowLocalModels = true;
|
| 778 |
+
env.localModelPath = '/vendor/'; // model id is appended → /vendor/moonshine-tiny-ONNX/…
|
| 779 |
+
this.asr = await pipeline('automatic-speech-recognition', 'moonshine-tiny-ONNX', { dtype: 'q8', device: 'wasm' });
|
| 780 |
|
| 781 |
// 3) the mic: Silero VAD segments speech; onSpeechEnd is our send trigger
|
| 782 |
this.vad = await window.vad.MicVAD.new({
|
frontend/vendor/moonshine-tiny-ONNX/config.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"MoonshineForConditionalGeneration"
|
| 4 |
+
],
|
| 5 |
+
"attention_bias": false,
|
| 6 |
+
"attention_dropout": 0.0,
|
| 7 |
+
"bos_token_id": 1,
|
| 8 |
+
"decoder_hidden_act": "silu",
|
| 9 |
+
"decoder_num_attention_heads": 8,
|
| 10 |
+
"decoder_num_hidden_layers": 6,
|
| 11 |
+
"decoder_num_key_value_heads": 8,
|
| 12 |
+
"decoder_start_token_id": 1,
|
| 13 |
+
"encoder_hidden_act": "gelu",
|
| 14 |
+
"encoder_num_attention_heads": 8,
|
| 15 |
+
"encoder_num_hidden_layers": 6,
|
| 16 |
+
"encoder_num_key_value_heads": 8,
|
| 17 |
+
"eos_token_id": 2,
|
| 18 |
+
"hidden_size": 288,
|
| 19 |
+
"initializer_range": 0.02,
|
| 20 |
+
"intermediate_size": 1152,
|
| 21 |
+
"is_encoder_decoder": true,
|
| 22 |
+
"max_position_embeddings": 512,
|
| 23 |
+
"model_type": "moonshine",
|
| 24 |
+
"num_attention_heads": 8,
|
| 25 |
+
"num_hidden_layers": 6,
|
| 26 |
+
"num_key_value_heads": 8,
|
| 27 |
+
"partial_rotary_factor": 0.9,
|
| 28 |
+
"rope_scaling": null,
|
| 29 |
+
"rope_theta": 10000.0,
|
| 30 |
+
"torch_dtype": "float32",
|
| 31 |
+
"transformers_version": "4.48.0.dev0",
|
| 32 |
+
"use_cache": true,
|
| 33 |
+
"vocab_size": 32768
|
| 34 |
+
}
|
frontend/vendor/moonshine-tiny-ONNX/generation_config.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_from_model_config": true,
|
| 3 |
+
"bos_token_id": 1,
|
| 4 |
+
"decoder_start_token_id": 1,
|
| 5 |
+
"eos_token_id": 2,
|
| 6 |
+
"transformers_version": "4.47.0.dev0"
|
| 7 |
+
}
|
frontend/vendor/moonshine-tiny-ONNX/onnx/decoder_model_merged_quantized.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:eed87831c3a6103534aae7d47a5d485025c659a1323901513961c39fe8a1a367
|
| 3 |
+
size 20243286
|
frontend/vendor/moonshine-tiny-ONNX/onnx/encoder_model_quantized.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c6fc4b7bc5af75c0591fd157a1f3829b533d18e9769a888fd95a62e470dd4f4a
|
| 3 |
+
size 7937661
|
frontend/vendor/moonshine-tiny-ONNX/preprocessor_config.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"feature_extractor_type": "MoonshineFeatureExtractor",
|
| 3 |
+
"processor_class": "MoonshineProcessor",
|
| 4 |
+
"sampling_rate": 16000
|
| 5 |
+
}
|
frontend/vendor/moonshine-tiny-ONNX/special_tokens_map.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{}
|
frontend/vendor/moonshine-tiny-ONNX/tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/vendor/moonshine-tiny-ONNX/tokenizer_config.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|