Commit Graph
2967 Commits
Author SHA1 Message Date
li-lizhe ae5c4ccdec Remove hard torchaudio dependency for inference; add kaldi-native-fbank fbank backend (#3526)
* Remove hard torchaudio dependency for inference; add kaldi-native-fbank fbank backend

Make torchaudio an optional dependency for the inference path so FunASR
can run on Ascend NPU (aarch64) servers, where no matching torchaudio
wheel exists (Huawei's Ascend torch is version-decoupled from the PyTorch
upstream release line).

- Add funasr/utils/fbank.py: an fbank shim that delegates to
  torchaudio.compliance.kaldi when torchaudio is installed, otherwise
  falls back to kaldi-native-fbank (a torch-free C++ library with aarch64
  wheels). Options and frame-shift API are mapped to torchaudio semantics
  so outputs are equivalent.
- Switch funasr/frontends/wav_frontend.py, funasr/utils/speaker_utils.py
  and funasr/models/campplus/utils.py to the shim.
- Make the torchaudio import optional in funasr/utils/load_utils.py
  (resampler falls back to librosa).

No device-specific branching is introduced — a pure backend fallback that
also benefits CPU-only and other accelerator platforms.

Verified end-to-end on Ascend 910B (npu:0) with torchaudio absent:
paraformer-large loads and infers correctly, RTF ~0.016 (~60x realtime).

* Make torchaudio import optional in paraformer_v2, fun_asr_nano and dataset preprocessors

Follow-up to the inference-path change: make the remaining top-level
torchaudio imports optional so these modules import cleanly when
torchaudio is not installed (e.g. on Ascend NPU servers).

- funasr/models/paraformer_v2_community/model.py
- funasr/models/fun_asr_nano/tools/utils.py
- funasr/datasets/audio_datasets/preprocessor.py
- funasr/datasets/llm_datasets/preprocessor.py

Functions that still require torchaudio (forced_align, Resample) degrade
to a clear error only when called, rather than a hard import failure.

* Address review: declare knf extra, harden fbank fallback and torchaudio guards

Respond to maintainer review feedback.

- Declare kaldi-native-fbank as an optional 'knf' extra in setup.py; the
  fbank module now raises an actionable ImportError only when fbank() is
  actually called with neither torchaudio nor kaldi-native-fbank installed
  (previously it failed at import time with a bare ModuleNotFoundError).
- Harden the fbank fallback contract: handle the channel argument explicitly
  and reject torchaudio-only options (subtract_mean, min_duration, VTLN
  warping, non-default blackman_coeff) with NotImplementedError instead of
  silently dropping them via **kwargs.
- Add a shared guard funasr/utils/torchaudio_compat.py and use it for
  resampling, forced alignment and speed perturbation so a missing torchaudio
  fails loudly instead of returning a silently wrong result (empty alignment).
- Add regression tests (tests/test_torchaudio_optional.py) that import the
  affected modules with torchaudio absent.
2026-08-27 00:23:11 +08:00
zhifu gao b2915020b2 chore(release): prepare 1.4.4 (#3530)
Prepare the FunASR 1.4.4 hotfix release with realtime WebSocket concurrency batching, PyTorch AMP compatibility, and correct runtime-binding exceptions.

Signed-off-by: LauraGPT <[email protected]>
2026-08-26 23:36:15 +08:00
zhifu gao 55daa5a193 fix(realtime): batch concurrent websocket decoding (#3529)
Fix the realtime WebSocket concurrency regression by removing the process-wide session lock and batching compatible vLLM decode requests. Isolate per-session VAD runtime state while sharing encoder weights, keep batch failures contained, and document reproducible concurrency benchmarks.

Fixes #3528

Signed-off-by: LauraGPT <[email protected]>
2026-08-26 23:30:20 +08:00
谢翊凡 9413d7d768 fix: use torch.amp via compatibility shim (#3518)
Use the non-deprecated torch.amp APIs when available while preserving the torch.cuda.amp fallback and legacy autocast argument semantics on older PyTorch releases.
2026-08-26 20:10:53 +08:00
zhifu gao eedd4e22d1 chore(release): prepare 1.4.3 (#3519)
Release FunASR 1.4.3 with the optional Silero VAD adapter and scalable fixed-K diarization clustering.\n\nSigned-off-by: zhifu gao <[email protected]>
2026-08-21 11:39:49 +08:00
tandede 9dbf3e1c08 fix(diarization): scale clustering with known speaker counts 2026-08-20 01:15:55 +08:00
LauraGPT e8ea59a02c fix(vad): preserve Silero ONNX CPU inputs 2026-08-14 07:35:21 +00:00
LauraGPT 419674e544 fix(vad): keep Silero inputs on the model device 2026-08-14 07:32:23 +00:00
wuhongsheng 22920822a2 feat(vad): add Silero VAD adapter 2026-08-14 11:13:32 +08:00
LauraGPT 8c08e2636b chore: prepare FunASR 1.4.2 release
Signed-off-by: LauraGPT <[email protected]>
2026-08-11 18:23:20 +00:00
May 112b80fa0b fix(train): initialize DeepSpeed mode from resolved config (#3471)
Resolve distributed trainer settings once with top-level precedence and backwards-compatible train_conf fallbacks. Remove consumed mode keys before expanding trainer_conf, reject simultaneous FSDP and DeepSpeed, and cover the behavior with focused tests.
2026-08-05 11:35:53 +08:00
May d410a5652d fix(train): align DDP no_sync with gradient accumulation (#3472)
Synchronize DDP/FSDP gradients on the final microbatch of each accumulation window.

Verified with a two-rank CPU/Gloo reproduction, py_compile, diff checks, and a clean synthetic merge against current main.
2026-08-05 11:32:24 +08:00
zhifu gao 6829ba7845 fix(auto-model): align split punctuation tokens (#3469)
Preserve subtitle segmentation when punctuation token boundaries split a timestamped ASR word.

Signed-off-by: LauraGPT <[email protected]>
2026-08-04 14:27:55 +08:00
LauraGPT 7a974018c2 chore: prepare FunASR 1.4.1 release
Signed-off-by: LauraGPT <[email protected]>
2026-08-04 02:23:14 +00:00
zhifu gao 187dc73f08 fix: route paraformer-en to the English HF model (#3466)
Route the Hugging Face paraformer-en alias to the official English checkpoint and keep the behavior covered by a regression test.
2026-08-04 10:06:33 +08:00
张思远 (ZhangSiYuan)andClaude 0738581f4b feat(nano): support LoRA finetuning of the Qwen3 LLM (#3456)
* feat(nano): support LoRA finetuning of the Qwen3 LLM

The FunASR-Nano model config already declares llm_conf.use_lora and
llm_conf.lora_conf (r/lora_alpha/lora_dropout/target_modules), but nothing
consumed them: use_lora was silently ignored and training fell back to the
full-parameter LLM path. Wire it up:

- When llm_conf.use_lora is true, replace the LLM target Linear layers
  (default q_proj/v_proj) with lora.Linear adapters, sharing the frozen base
  weight and adding trainable lora_A/lora_B. The adapter params are created in
  the base weight's dtype (bf16), so the LoRA path does not depend on autocast.
- Pairs with the existing lora_only / mark_only_lora_as_trainable flow in
  train.py / train_ds.py: lora_only=true freezes every non-LoRA parameter for
  pure-LoRA training; lora_only=false + unfrozen encoder/adaptor conf keeps
  them trainable while LoRA-tweaking only the LLM.
- Checkpoints save the full state dict (unchanged base + adapter params), so a
  LoRA run can be resumed or decoded with the same use_lora=true config; for a
  standalone deployment checkpoint, fold with W' = W + alpha/r * B @ A.
- Add lora_finetune.sh and document the recipe in finetune.md / finetune_zh.md.

Validated end-to-end with the real model: 56 adapters injected (28 Qwen3
layers x q_proj+v_proj), optimizer updates only the 112 LoRA params, and a
2-step smoke training run through funasr-train-ds completes and saves a
checkpoint whose lora keys are bf16 and match the base dtype.

Co-Authored-By: Claude <[email protected]>

* test(nano): add offline unit tests for LoRA injection

Drive FunASRNano._apply_lora_to_llm against a tiny fake LLM mirroring the
Qwen3 parameter layout (layers.<i>.self_attn.{q,k,v,o}_proj / mlp.{gate,up,down}_proj).
No model download needed.

Covers the points requested in review:
1. only configured target modules are replaced;
2. the initial output matches the original linear layers (lora_B init zero);
3. base weights stay frozen while lora_A/lora_B are trainable (llm_conf.freeze
   applied before injection, as in the real init path);
4. a non-zero adapter survives a state-dict save/load round trip and train/eval
   transitions (including the eval-merge / train-unmerge convention);
5. the no-matching-target configuration is an explicit no-op with a warning.

Verified honest: on upstream main (no _apply_lora_to_llm) all 7 fail with
AttributeError; with the fix 7/7 pass. Full nano set: 34 passed.

Co-Authored-By: Claude <[email protected]>

---------

Co-authored-by: Claude <[email protected]>
2026-08-03 14:28:02 +08:00
张思远 (ZhangSiYuan)andClaude 036ed6936b fix(trainer): avoid KeyError when a checkpoint is saved at an unvalidated step (#3455)
* fix(trainer): avoid KeyError when a checkpoint is saved at an unvalidated step

When save_checkpoint_interval is not a multiple of validate_interval, a
checkpoint can be saved at a step that was never validated. The best-ckpt
comparison then indexes val_acc/val_loss_step_or_epoch[ckpt_name], raising
KeyError right after the checkpoint was already written and aborting the run.

Guard both the DeepSpeed and the torch.save checkpoint paths with .get() so
an unvalidated checkpoint is skipped for the "best" bookkeeping (and logged)
instead of crashing; fall back to 0.0 when recording saved_ckpts.

Co-Authored-By: Claude <[email protected]>

* fix(trainer): exclude unvalidated-step checkpoints from best-model ranking

Address review feedback on PR #3455. A checkpoint saved at a step that was
never validated (save_checkpoint_interval not a multiple of
validate_interval) used to be inserted into `saved_ckpts` with a fabricated
score of 0.0. Under loss-based ranking that synthetic "perfect" loss could
evict a real validated best checkpoint via keep_nbest_models pruning.

Now such checkpoints are kept on disk but excluded from `saved_ckpts`
entirely, so they never compete in best-model ranking or pruning, and
`best_step_or_epoch` only ever references validated checkpoints.

Adds regression coverage for both loss and acc ranking on the DeepSpeed
and torch.save paths, asserting an unvalidated checkpoint cannot evict a
validated best checkpoint.

* test(trainer): make unvalidated-ckpt regression catch the DeepSpeed+acc case

The fake DeepSpeed engine now writes a placeholder file per tag (mirroring
DeepSpeed's per-tag checkpoint dirs), so keep_nbest_models pruning's
smart_remove() is observable. This closes a gap where the [DeepSpeed, acc]
combination passed on the buggy code: under acc ranking the fabricated 0.0
is the minimum, so pruning deletes the unvalidated checkpoint itself rather
than the validated best, and without an on-disk artifact that deletion was
invisible.

With the fix, all 8 cases pass; on the previous code all 4 unvalidated-step
cases now fail (loss: fabricated 0.0 evicts the validated best; acc: the
unvalidated checkpoint file is pruned).

* fix(trainer): apply the same unvalidated-step guard to the non-DeepSpeed Trainer

`funasr-train` (funasr/train_utils/trainer.py) shares the identical
checkpoint-ranking code as trainer_ds.py and had the same bug: direct
indexing of `val_{acc,loss}_step_or_epoch[ckpt_name]` raised KeyError when
a checkpoint was saved at a step that was never validated, and the
keep_nbest_models bookkeeping inserted a fabricated score for such
checkpoints.

Apply the same fix: checkpoints saved at an unvalidated step are kept on
disk but excluded from saved_ckpts (no synthetic score), best_step_or_epoch
only ever references validated checkpoints, and the metric dicts are read
via .get().

Tests now parametrize over all three checkpointing paths (trainer_ds
torch.save, trainer_ds DeepSpeed, and trainer torch.save) x loss/acc.
On upstream main all 6 unvalidated-step cases fail with
`KeyError: 'model.pt.ep1.2'`; with the fix all 12 cases pass.

---------

Co-authored-by: Claude <[email protected]>
2026-08-03 14:19:25 +08:00
zhifu gao e65f6ba080 chore: prepare FunASR 1.4.0 release (#3444)
Advance the package version to 1.4.0, document the Python and tagged-source release changes in four languages, and enforce the release numbering contract.

Signed-off-by: LauraGPT <[email protected]>
2026-07-30 04:35:26 +08:00
zhifu gao 60827ffbeb fix(auto-model): report vda model typo (#3443)
Fail immediately with an actionable parameter name when `vda_model` is supplied, instead of silently disabling the VAD-dependent long-audio and speaker pipeline.

Signed-off-by: Zhifu Gao <[email protected]>
2026-07-30 04:13:35 +08:00
zhifu gao 16cd165ac3 chore: release FunASR 1.3.30 (#3436)
Signed-off-by: LauraGPT <[email protected]>
2026-07-27 15:25:14 +00:00
zhifu gao 763ee06e37 Decode container-formatted audio bytes before inference (#3435)
Decode encoded audio containers before inference while preserving the raw PCM fast path. Rewind file-like decoder fallbacks and support ffmpeg stdin decoding.

Signed-off-by: LauraGPT <[email protected]>
2026-07-27 14:55:49 +00:00
zhifu gao 0a9cc00642 fix(auto-model): preserve VAD segments on punctuation mismatch (#3434)
Fall back to VAD-aligned string sentence records when a sized punctuation array cannot align with long-audio ASR timestamps.

Verified against both reporter attachments: 103.mp3 recovers 199 sentence records and 2980.mp3 remains byte-for-byte unchanged.

Signed-off-by: LauraGPT <[email protected]>
2026-07-27 21:40:45 +08:00
zhifu gao cbed336e56 fix(server): return speaker labels for spk requests (#3433)
Make spk=true functional across vLLM and fallback server paths, preserve speaker labels in verbose_json segments, and accept sentence_info sentence text.
2026-07-27 20:01:21 +08:00
zhifu gao 866cf910dc fix(server): allow trusted browser origins (#3427)
Add explicit, default-disabled trusted browser origins to funasr-server, with CLI coverage and bilingual troubleshooting guidance.
2026-07-27 05:57:06 +08:00
zhifu gaoandzhifu gao 8a34247dc5 chore: release FunASR 1.3.29 (#3415)
Co-authored-by: zhifu gao <[email protected]>
2026-07-24 20:32:32 +08:00
zhifu gaoandzhifu gao 99b703009a Return VAD sentence timestamps for SenseVoice (#3414)
Co-authored-by: zhifu gao <[email protected]>
2026-07-24 20:20:32 +08:00
zhifu gaoandzhifu gao 689cc945b4 chore: release FunASR 1.3.28 (#3409)
* chore: release FunASR 1.3.28

* fix: handle realtime websocket errors reliably

---------

Co-authored-by: zhifu gao <[email protected]>
2026-07-24 15:41:04 +08:00
zhifu gaoandzhifu gao c8f849f203 fix: preserve stable realtime transcript on lock (#3408)
Co-authored-by: zhifu gao <[email protected]>
2026-07-24 14:50:54 +08:00
zhifu gao 878da6e513 fix: align SenseVoice sentence timestamps (#3407) 2026-07-24 12:23:37 +08:00
zhifu gao 3a5fa06f0e chore: release FunASR 1.3.27 (#3403) 2026-07-24 02:02:38 +08:00
zhifu gao e0fbedfbac fix(server): reuse Fun-ASR-Nano fallback after vLLM failure (#3402)
Closes #3401.
2026-07-24 01:33:53 +08:00
zhifu gao 8d9b34bebc fix(server): report detected transcription language (#3400) 2026-07-23 22:24:23 +08:00
zhifu gaoandLauraGPT f5e8a785fd chore: release FunASR 1.3.26 (#3325)
Co-authored-by: LauraGPT <[email protected]>
2026-07-23 00:14:15 +08:00
zhifu gaoandLauraGPT 033b70de2c fix: honor server hub for default Nano model (#3324)
Co-authored-by: LauraGPT <[email protected]>
2026-07-23 00:11:23 +08:00
zhifu gaoandLauraGPT 006d69789f release: bump funasr to 1.3.25 (#3318)
Co-authored-by: LauraGPT <[email protected]>
2026-07-22 23:11:29 +08:00
zhifu gaoandLauraGPT 5133663a9e feat: add realtime postprocess hotwords (#3317)
Co-authored-by: LauraGPT <[email protected]>
2026-07-22 23:05:54 +08:00
zhifu gaoandLauraGPT 622df23473 release: bump funasr to 1.3.24 (#3316)
Co-authored-by: LauraGPT <[email protected]>
2026-07-22 22:46:33 +08:00
liudonghua 16e3654942 feat(server): support custom model path and hub
Adds funasr-server --model-path/--hub support with maintainer follow-up for default Fun-ASR-Nano hub routing and custom fallback loading. Validated with py_compile, focused CLI/server tests, and git diff check.
2026-07-22 17:54:16 +08:00
LauraGPT dc9758dd73 release: prepare funasr 1.3.23 2026-07-22 09:17:25 +00:00
zhifu gao 38e421b0c4 release: prepare funasr 1.3.22 (#3293) 2026-07-19 19:21:01 +08:00
zhifu gao 6be08b4874 fix(server): segment text-only OpenAI transcription responses (#3292) 2026-07-19 19:18:54 +08:00
zhifu gao ac07ca2616 fix: lazy load top-level AutoModel exports
Fix fresh-install import behavior when torch has not been installed yet, and prepare funasr 1.3.21.
2026-07-19 18:27:49 +08:00
zhifu gao f2122795a4 release: prepare funasr 1.3.20 2026-07-19 17:28:35 +08:00
zhifu gao 2ac68a7a0c Release FunASR 1.3.19
Bump package version to 1.3.19 and announce the PyPI release.
2026-07-19 09:59:24 +08:00
zhifu gao 1c7a604818 Release FunASR 1.3.18 (#3255) 2026-07-19 08:59:11 +08:00
zhifu gao d431003077 Fix CLI SRT sentence segmentation (#3254) 2026-07-19 08:54:44 +08:00
zhifu gao 98536eacb6 Release FunASR 1.3.17 (#3252) 2026-07-19 05:58:31 +08:00
zhifu gao 9dd15458d4 Add realtime WebSocket session stats logging
Adds an opt-in realtime WebSocket session stats log for long-running speaker-enabled sessions. Validation: PYTHONPATH=. python -m pytest tests/test_realtime_ws_service.py -q (23 passed), compileall, and git diff --check.
2026-07-19 04:06:44 +08:00
zhifu gao d41ca43b33 Release FunASR 1.3.16 (#3246)
* release v1.3.16

* Package realtime WebSocket server
2026-07-18 02:00:57 +08:00
zhifu gao 59e68743a3 release v1.3.15
Roll up the verified streaming VAD, Fun-ASR-Nano, CLI hotword, tokenizer, and metrics fixes merged since v1.3.14.
2026-07-17 10:48:04 +00:00