Spaces:
Sleeping
Sleeping
Commit History
-
step 2: add app_minimal.py — zero-shot baseline for rebuild.
Broulaye Doumbia34edd5f -
fix read me
Broulaye Doumbiada3a060 -
restructuring
Broulaye Doumbia76aac1b
-
Add torchcodec install for datasets 4.x audio decoding
jefffffff9 +1: Claude Opus 4.7datasets >= 4.0 uses torchcodec as the audio backend; prepare_dataset would fail with ImportError on batch['audio'] without it. - scripts/runpod_setup.sh: pip install torchcodec with torch-version pinning fallback (0.1/0.2/0.3/0.4 → torch 2.4/2.5/2.6/2.7+) - kaggle_master_trainer.ipynb Cell 2: defensive try/except install so the notebook is self-healing on any fresh environment Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>bb78cbf -
Prepare training stack for RunPod: env-aware notebook + bootstrap script
jefffffff9 +1: Claude Sonnet 4.6Cell 3 now auto-detects Kaggle (/kaggle/working), Colab (/content), RunPod (/workspace), or local — and adjusts defaults per environment. On RunPod the base model defaults to whisper-large-v3-turbo (128 mel bins, matches the Space and fits in 24 GB VRAM); on Kaggle T4 it stays on whisper-small to avoid OOM. Batch size / grad accumulation tuned per card (8x4 on 24 GB vs 16x2 on T4, both yield effective batch 32). TRAIN_LANG, HF_USERNAME, and WHISPER_MODEL_ID are now env-var overridable so the notebook can be driven headlessly from a shell. scripts/runpod_setup.sh bootstraps a fresh pod: - clones the Space repo into /workspace/sahel-voice - installs training deps (peft, evaluate, tensorboard, etc.) that are intentionally absent from the HF Spaces runtime requirements.txt - sources .env for HF_TOKEN; falls back to prompting the user - creates persistent checkpoint dirs on the Volume disk so adapters survive pod stop/start - prints GPU / VRAM sanity check at the end C…9049ef3
-
Fix jiwer crash on post-normalisation empty refs; register SLR106/105 datasets
jefffffff9 +1: Claude Sonnet 4.6compute_metrics: pre-apply lowercasing + punctuation removal before filtering empty references — a label like "?" passes r.strip() but becomes "" after RemovePunctuation, causing jiwer to raise ValueError mid-evaluation. Pass already-normalised strings directly to jiwer.cer / jiwer.wer so no second transform is applied. web_harvester: add commented-in registry entries for OpenSLR SLR106 (10k clean Guinea Pular utterances, 49 speakers, CC BY-SA 4.0) and SLR105 (Guinea radio corpus, Pular-tagged validation split). Both are uncommented once the audio is uploaded to HF — best available Guinea Pular ASR data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6682858 -
Fix SyntaxError in Cell 17: unterminated f-string literal
jefffffff9 +1: Claude Sonnet 4.6A bare newline inside a single-quoted f-string caused SyntaxError on Python 3.12+. Replace the literal newline with the \n escape sequence so the print statement is valid on a single line. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>58f431a -
Fix compute_metrics crash on empty eval references in Fula training
jefffffff9 +1: Claude Sonnet 4.6jiwer raises ValueError when a reference string decodes to empty (silent audio / all-padding labels). Filter out empty reference/ hypothesis pairs before calling jiwer.cer and jiwer.wer; guard the all-empty edge case by returning 0.0 metrics safely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3632a23
-
Add Adlam/Pular Fula integration: transliterator + 3 new datasets + normalisation pipeline
jefffffff9 +1: Claude Sonnet 4.6- src/data/adlam.py: full Adlam↔Latin transliterator for Pular (Guinea Fula) — bidirectional char map (U+1E900–U+1E95F), digraph-aware latin_to_adlam(), contains_adlam(), normalize_pular() (Adlam→Latin + NFC + lowercase) - src/data/web_harvester.py: add 3 Fula training sources to HF_DATASET_REGISTRY: Pullo-Africa-Protagonist/Fula-pular (9,761 audio rows, primary), guizme/adlam_fulfulde (51 Adlam-script rows, auto-converted to Latin) - notebooks/kaggle_master_trainer.ipynb: Cell 11 gets inline _normalize_pular (Adlam→Latin); Cell 12 applies it for lang=='ful' in prepare_dataset - app.py: import normalize_pular; apply in _do_asr and _convo_pipeline for Fula; update Self-Teaching tab help text to list all 3 Fula datasets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ced078c -
Fix language mixing: per-language prompts + Mali Bambara / Guinea Pular context
jefffffff9 +1: Claude Sonnet 4.6Root cause: one generic system prompt for all languages with no language code injected. The LLM had no instructions to stay in one dialect, so it mixed Bambara and Fula words freely. app.py: - SUPPORTED_LANGUAGES: labels now say "Bambara — Mali" and "Fula / Pular — Guinea" - LANG_CONTEXT dict: per-language country, region, script, phonetic rules, and explicit "do_not_mix" field naming the languages to never blend in - _build_system_prompt(language_code, vocab): generates a language-specific system prompt that opens with "You MUST respond exclusively in {lang} ({country})" and lists exactly which other languages must NOT appear in responses - _get_vocab_context_for(language_code): filters vocabulary cache to only entries tagged [bam] or [ful] — LLM never sees the other language's words in its context - _build_messages: uses _build_system_prompt + filtered vocab instead of the single generic template - LLM fallback messages now cover bam (Mali Bambara), ful (Guinea Pular), and…40cf84d
-
Phase 3: Voice-to-Voice S2S pipeline — F5-TTS, LLM brain, CER metric
jefffffff9 +1: Claude Sonnet 4.6app.py: - Add LLM_MODEL_ID env var (default: Qwen/Qwen2.5-72B-Instruct) - Import GemmaClient + bam_normalize at module level - Add _voice_ref_path / _voice_ref_text / _llm_client state - Add set_voice_reference(): converts MP3->24kHz WAV, auto-transcribes - Add _convo_pipeline(): ASR -> bam_normalize -> LLM (phonetic Bambara system prompt) -> F5-TTS (voice ref) with MMS-TTS fallback - handle_ask() accepts convo_mode=bool, routes to _convo_pipeline or the original sensor pipeline accordingly - Tab 1 UI: Conversation Mode toggle, Voice Reference upload accordion, stop_recording auto-submit for true back-to-back loop src/tts/f5_tts.py (new): - Lazy-loaded F5TTS wrapper; synthesize() with ref_wav + ref_text - to_wav_24k() resampler (F5-TTS needs 24 kHz input) - Graceful fallback (returns None) when f5-tts not installed src/data/bam_normalize.py (new): - _bam_norm(): ou->u, dj->j, gn->ny, ch->c, oo->o-open, ee->e-open - Used at inference (app.py) and training (notebook Cell 11) req…8952fff
-
Fix Cell 16 ValueError: load model fp32 so AMP gradient scaler works
jefffffff9 +1: Claude Sonnet 4.6Root cause: model loaded in fp16 + fp16=True training args causes GradScaler to see fp16 params and raise "Attempting to unscale FP16 gradients". Fix: load fp32, let AMP cast internally during forward pass. Cell 13: torch_dtype float16 -> float32; remove manual gradient_checkpointing_enable Cell 14: remove explicit .to(float16) cast in data collator (AMP handles it) Cell 15: gradient_checkpointing False->True; remove deprecated logging_dir kwarg Cell 17: remove .half() on eval features (fp32 model needs fp32 input) Cell 19: fix f-string ternary precedence so commit msg always includes all fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>cd017e2 -
Fix Wikipedia and HF harvest buttons
jefffffff9 +1: Claude Sonnet 4.6Wikipedia fix: - Add User-Agent header to all requests (Wikipedia API returns 403 without it) - Extract shared _upload_jsonl() helper to reduce code duplication HF harvest fix: - Remove audio re-upload approach (500 HTTP requests -> Gradio timeout) - Instead write dataset references to dataset_sources.jsonl on the Hub - One small file upload (~instant) instead of gigabytes of audio - Kaggle notebook Cell 4 now reads dataset_sources.jsonl dynamically: any dataset registered in Space Self-Teaching tab is automatically picked up at training time with no notebook edits needed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a5737ac
-
Fix eval_loss nan + add generation_config to Seq2SeqTrainer
jefffffff9 +1: Claude Sonnet 4.61. Seq2SeqTrainer now receives generation_config=model.generation_config explicitly -- ensures forced_decoder_ids is applied during eval's generate() call, fixing the '!!!!!' prediction output 2. eval_loss nan handled gracefully in cells 17, 19, 20 -- transformers 5.x predict_with_generate=True does not compute loss, always returns nan; display shows 'n/a (generation-based eval)' instead of crashing on .4f Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9f07d46 -
Fix GenerationConfig deprecation warning in cells 13 and 16
jefffffff9 +1: Claude Sonnet 4.6forced_decoder_ids/suppress_tokens belong in generation_config not model.config. Fixes the warning before it becomes an exception in transformers v4.41+. Also saves generation_config alongside the model checkpoint so it loads correctly from the HF hub. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1f2993e -
Auto-cap MAX_STEPS based on dataset size after Cell 12 builds train_ds
jefffffff9 +1: Claude Sonnet 4.64000 steps on 11 samples = 2-hour wasted run. New rule: cap at max(200, steps_per_epoch * 20) so small/synthetic datasets complete in ~5 min while full datasets (5000+ samples) still run the full MAX_STEPS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>73a3f3a -
Fix Cell 15: detect eval_strategy vs evaluation_strategy at runtime
jefffffff9 +1: Claude Sonnet 4.6transformers 4.x: evaluation_strategy; transformers 4.45+: eval_strategy. Kaggle's transformers 5.x raises TypeError on eval_strategy. Use inspect to detect the accepted param name and unpack via **{key: value}. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1c462f3 -
Proactive notebook audit: fix 5 issues before they cause errors
jefffffff9 +1: Claude Sonnet 4.61. Cell 3: remove dead LORA_R/ALPHA/DROPOUT/TARGETS vars (PEFT removed) 2. Cell 13: fix train_test_split test_size -- was float(0.05) which gives 0 eval samples on small datasets; now max(1, int(0.05 * n)) 3. Cell 22: remove forced_decoder_ids kwarg from model.generate() -- transformers 5.x removed this param; config already has it set 4. Cell 13: remove num_proc=2 from waxal map (multiprocessing + audio can hang on Kaggle when dataset is small) 5. Update stale markdown cells (LoRA/PEFT/8-bit references removed) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aef60bc -
Simplify Cell 2: no restart needed since PEFT is removed
jefffffff9 +1: Claude Sonnet 4.6Without PEFT, the transformers/numpy/scipy downgrade is unnecessary. Kaggle system packages (transformers 5.x, numpy 2.x, etc.) work fine. Cell 2 now only installs jiwer which Kaggle doesn't ship. No kernel restart, no sentinel file, no 3-minute wait. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8e41441 -
Fix Cell 16 TypeError: replace PEFT LoRA with freeze/unfreeze fine-tuning
jefffffff9 +1: Claude Sonnet 4.6Root cause: PeftModelForSeq2SeqLM.forward wraps the entire WhisperForConditionalGeneration in BaseTuner, whose forward(*args, **kwargs) combined with transformers 5.x @auto_docstring causes input_ids to be passed to WhisperDecoder twice -- TypeError even when no decoder layers have LoRA. The issue is in the PEFT model wrapper itself, not in which layers are targeted. Fix: remove PEFT entirely. Freeze all params, unfreeze last 2 decoder layers + layer_norm + proj_out (~5% trainable, same capacity as LoRA r=32). Standard Seq2SeqTrainer works cleanly with the unfrozen plain model. Also update push commit message from 'LoRA adapter' to 'fine-tuned checkpoint'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6dc0dfc -
Fix Cell 16 TypeError: target encoder-only LoRA to avoid PEFT/transformers 5.x conflict
jefffffff9 +1: Claude Sonnet 4.6PEFT 0.18.x + transformers 5.x: WhisperDecoder.forward receives input_ids via both positional args and kwargs when LoRA wraps decoder layers, causing TypeError('got multiple values for keyword argument input_ids'). Fix: LORA_TARGETS changed from list ['q_proj','v_proj'] (matches all layers) to regex that targets only encoder self-attention projections. The encoder processes audio features and has no input_ids, so the conflict cannot occur. Also adds model.config.use_cache = False (required with gradient checkpointing). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c37ce59
-
Fix Cell 14: cast input_features to fp16 in collator
jefffffff9 +1: Claude Sonnet 4.6Model is loaded in fp16 but the feature extractor returns float32. Whisper's conv1 layer raises RuntimeError on the dtype mismatch. Cast batch['input_features'] to torch.float16 in the collator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3ed28bd -
Fix Cell 16: remove tokenizer arg from Seq2SeqTrainer (renamed in transformers 5.x)
jefffffff9 +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>829fd3d -
Fix Cell 14: replace evaluate.load('wer') with jiwer directly
jefffffff9 +1: Claude Sonnet 4.6evaluate==0.4.2 uses use_auth_token which was removed from huggingface-hub>=1.0 -- raises AttributeError at runtime. Replaced with jiwer.wer() + jiwer.Compose transforms, which needs no network call and is already installed. Also removed evaluate from Cell 2 install list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c1bce9f -
Fix Cell 13: drop bitsandbytes, load whisper-small in fp16
jefffffff9 +1: Claude Sonnet 4.6bitsandbytes 8-bit requires libnvJitLink.so.13 which is absent on Kaggle CUDA 13. whisper-small (244MB) fits in T4 16GB in fp16 with room to spare -- 8-bit quantization is unnecessary. Cell 13: WhisperForConditionalGeneration loaded via direct module path (avoids torchvision chain), fp16, .to(device), gradient_checkpointing enabled on the model directly. Cell 15: set gradient_checkpointing=False in TrainingArguments since it is already enabled on the model in Cell 13 (setting both causes a warning and double-wrapping). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8cf3564 -
Fix Cell 2: restart kernel after torchvision reinstall using sentinel file
jefffffff9 +1: Claude Sonnet 4.6Reinstalling torchvision in-session fixes disk but not memory -- the mismatched CUDA 12.8 build stays loaded until kernel restart. Cell 2 now: 1. Detects if sentinel /kaggle/working/.torchvision_fixed exists 2. If not: installs correct torchvision + all packages, creates sentinel, restarts kernel via IPython.kernel.do_shutdown(restart=True) 3. If yes: skips restart (already fixed), prints torch/CUDA version The sentinel persists in /kaggle/working for the session so the restart only happens once -- re-running the cell is safe. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c3a3cb7 -
Cell 12: never raise, let Cell 12b handle no-data case gracefully
jefffffff9 +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a481b98 -
Cell 4: remove Common Voice (moved to Mozilla Data Collective, off HF)
jefffffff9 +1: Claude Sonnet 4.6Common Voice Bambara (bm) and Fula (ff) are no longer on HuggingFace. EXTERNAL_DATASETS is now empty with commented placeholder. Bambara training path: user corrections from sahel-agri-feedback only. Fula training path: WaxalNLP ful_asr (Cell 8) + corrections. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c8517b6 -
Fix Cell 12: add diagnostics + synthetic fallback cell (12b)
jefffffff9 +1: Claude Sonnet 4.6Cell 12 now prints which sources loaded and why before raising so the user knows exactly what to fix (HF_TOKEN not attached, Common Voice terms not accepted, etc.). Cell 12b (new): synthetic fallback using vocabulary.jsonl entries and silent audio so the training pipeline can be validated end-to-end even before real data is available. Skips itself if Cell 12 succeeded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>262db3e -
Fix Cell 11: bypass WhisperProcessor entirely to avoid torchvision crash
jefffffff9 +1: Claude Sonnet 4.6WhisperProcessor -> processing_utils -> image_utils -> torchvision fails when torch CUDA 13.0 and torchvision CUDA 12.8 are mismatched in memory (reinstalling torchvision in Cell 2 fixes disk but not the live process). Build processor from WhisperFeatureExtractor + WhisperTokenizer directly -- neither touches image_utils or torchvision. A minimal _Processor class exposes feature_extractor, tokenizer, get_decoder_prompt_ids, and save_pretrained, which is all the rest of the notebook needs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>65e1d64 -
Fix Cell 2: reinstall torchvision to match Kaggle CUDA version at runtime
jefffffff9 +1: Claude Sonnet 4.6Kaggle ships torch with CUDA 13.0 but torchvision was built against 12.8. Any import touching torchvision (incl. WhisperProcessor via image_utils) raises RuntimeError. Cell 2 now detects torch.version.cuda at runtime and reinstalls the matching torchvision wheel from the PyTorch index before any other package is imported. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>257bae8 -
Fix Cells 2+11: unpin torch, use direct WhisperProcessor import
jefffffff9 +1: Claude Sonnet 4.6Cell 2: remove torch==2.11.0 and torchaudio==2.11.0 pins. Kaggle pre-installs torch matched to its CUDA/Python environment; forcing 2.11.0 causes a torchvision version mismatch that breaks the torch._dynamo import chain on Python 3.12. Cell 11: import WhisperProcessor via direct module path (transformers.models.whisper.processing_whisper) instead of the top-level lazy loader, which triggers torchvision->torch._dynamo and raises ImportError: cannot import name 'is_opaque_value'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0d6357e -
Fix Cell 10: correct r3 assertion to 'visit now!' (URL strips link not preceding word)
jefffffff9 +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5a82441 -
Fix Cell 10: add ! and ? to allowlist, fix smoke test assertions
jefffffff9 +1: Claude Sonnet 4.6- _KEEP_PUNCT now includes ! and ? (valid in Bambara/Fula sentences) - Assertions corrected to match actual function output: parentheses are stripped (not in allowlist), tag content stays, repeated punctuation collapses to one character - All emoji removed so Windows charmap never triggers on push Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>295b7c6 -
Fix Cell 8: remove FLEURS fallback + strip emoji (charmap safe)
jefffffff9 +1: Claude Sonnet 4.6Notebook was still falling back to google/fleurs on Kaggle because the previous NotebookEdit did not land in the pushed version. This commit forces the correct state: - bam -> None (no WaxalNLP subset, skip cleanly) - ful -> 'ful_asr' (confirmed config name) - FLEURS removed entirely (datasets>=3.0 blocks its script loader) - All emoji replaced with ASCII so Windows charmap never triggers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f1012fa -
Fix Kaggle push: title slug + Windows UTF-8 encoding
jefffffff9 +1: Claude Sonnet 4.6- kernel-metadata.json: title changed to 'Sahel Voice Master Trainer' so its slug matches the id 'sahel-voice-master-trainer' - push_to_kaggle.sh: export PYTHONUTF8=1 + PYTHONIOENCODING=utf-8 so the Kaggle CLI reads emoji in notebook cells correctly on Windows Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>842ded5 -
Add Kaggle auto-sync: kernel-metadata.json + post-commit hook
jefffffff9 +1: Claude Sonnet 4.6- notebooks/kernel-metadata.json: tells the Kaggle API the kernel ID, title, GPU flag, and which .ipynb to upload - scripts/push_to_kaggle.sh: runs 'kaggle kernels push' from the notebooks/ directory; checks for kaggle CLI and kaggle.json first - .git/hooks/post-commit: detects if kaggle_master_trainer.ipynb was in the commit and calls push_to_kaggle.sh automatically Setup (one-time): pip install kaggle # download kaggle.json from kaggle.com → Settings → API cp ~/Downloads/kaggle.json ~/.kaggle/kaggle.json After that, every 'git commit' that touches the notebook will push the updated version to Kaggle automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4bd45bb -
Fix Cell 8: correct WaxalNLP subset names + drop fleurs fallback
jefffffff9 +1: Claude Sonnet 4.6Two bugs: 1. WaxalNLP has no 'bam' subset — Bambara is absent entirely. Correct Fula subset is 'ful_asr' (not 'ful'). WAXAL_SUBSET_MAP: bam→None (skip), ful→'ful_asr'. 2. google/fleurs uses a dataset script (fleurs.py) which datasets>=3.0 refuses to execute. Removed fleurs fallback entirely. Cell 4 updated: Common Voice Bambara ('bm') and Fula ('ff') enabled by default — Common Voice is now the primary large-scale source for Bambara since WaxalNLP has no bam subset. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bfa9d46 -
Fix Cell 6: replace get_last_checkpoint import with inline scanner
jefffffff9 +1: Claude Sonnet 4.6transformers.trainer_utils.get_last_checkpoint triggers a deep import chain (peft → generation → masking_utils → torch._dynamo) that breaks on Kaggle Python 3.12 before packages are settled. The replacement does the same thing (scan for checkpoint-N dirs, return the highest) with zero extra imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>39604b3 -
Add Kaggle Master Trainer — Deep Sleep fine-tuning notebook
jefffffff9 +1: Claude Sonnet 4.6Consolidates bootstrap_repos, train_colab, and train_fula_tts into a single self-contained Kaggle notebook. Key features: - Cell 3: all training config in one place (language, LoRA r/alpha, steps, batch size, repo IDs) - Cell 4: plug-in external dataset block (Common Voice etc.) - Cells 7-9: three data sources merged — sahel-agri-feedback corrections (upsampled ×3), WaxalNLP/FLEURS, external datasets - Cells 10-12: unified prepare_dataset with 16kHz resampling and language-aware text cleaning (Bambara: ɛ ɔ ŋ; Fula: ɓ ɗ ƴ ŋ ɲ) - Cell 13: Whisper-small loaded in 8-bit (BitsAndBytesConfig) + prepare_model_for_kbit_training + LoRA on decoder Q/V projections - Cell 6 + 16: resume-from-checkpoint via get_last_checkpoint() — Kaggle timeout safe - Cells 18-19: auto-incremented version tag (v1.0-bambara, v1.1-…) pushed as a Git tag to sahel-agri-adapters No dependency on src/ — fully standalone on Kaggle T4. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>427d4a2 -
Phase 2: Waxal TTS — Bambara voice output + Fula training notebook
jefffffff9 +1: Claude Sonnet 4.6TTS engine (src/tts/waxal_tts.py): - Bambara: MALIBA-AI/bambara-tts (non-Meta, Mali community, 10 native speakers) Loads via custom maliba-ai package; writes WAV to tempfile, reads back as numpy - Fula: ous-sow/fula-tts (our own model, loads once trained) Lazy-loads; gracefully reports 'not trained yet' until notebook is run - WaxalTTSEngine.audio_to_gradio() converts float32 → int16 for gr.Audio app_lab.py: - Imports WaxalTTSEngine; preloads both models at startup in background - _run_llm_and_tts() shared core: Gemma → memory → TTS → return audio tuple - process_audio() and process_text() now return 4-tuple (adds audio_out) - UI: added gr.Audio output widget with autoplay; status bar shows TTS readiness per language (🟢/🟡/🔴) Training notebook (notebooks/train_fula_tts.ipynb): - 9 cells: GPU check → install → HF login → config → load WaxalNLP ful_tts → prepare dataset (WAV + metadata.csv) → Coqui VITS trainer → push to HF Hub → synthesis test - Runs on Kaggle T4 (~2-3h); …dd38e25
-
Initial commit: Sahel-Agri Voice AI
jefffffff976db545