Skip to content

funasr_onnx / funasr_torch ContextualParaformer and SeacoParaformer: a hotword longer than 10 characters raises ValueError #3881

Closed

Description

@tanishqbaweja

ContextualParaformer.proc_hotword in runtime/python/onnxruntime/funasr_onnx/paraformer_bin.py (:409-433) and runtime/python/libtorch/funasr_torch/paraformer_bin.py (:367-389) builds the hotword input of the embedding model. SeacoParaformer inherits it in both packages:

hotwords = hotwords.split(" ")
hotwords_length = [len(i) - 1 for i in hotwords]
...
hotwords = pad_list(hotword_int, pad_value=0, max_len=10)
  • A hotword longer than 10 characters does not fit in its row of 10 ids, so the whole call fails with ValueError: could not broadcast input array from shape (12,) into shape (10,).
  • split(" ") turns repeated, leading or trailing spaces, and an empty hotword string, into empty hotwords. Each one becomes a row of padding (ten 0 ids), and its embedding is read at position len("") - 1 = -1, the last of the 10. It goes to the model as an extra hotword.

The exported embedding model takes exactly 10 ids per hotword. ContextualEmbedderExport in funasr/models/seaco_paraformer/export_meta.py (the Contextual Paraformer export uses its subclass ContextualEmbedderExport2) exports a [6, 10] dummy input and makes only num_hotwords dynamic, so model_eb.onnx declares its input as ['num_hotwords', 10]. The C++ runtime keeps the first max_hotword_len = 10 tokens of each hotword and skips hotwords that have no tokens (CompileHotwordEmbedding in runtime/onnxruntime/src/paraformer.cpp:565-607 and paraformer-torch.cpp:530-572). generate_hotwords_list in funasr/models splits with strip().split(), so it has no empty hotwords either.

Reproduction on main (0e52c3c), no model files: proc_hotword only needs the vocabulary, and the call fails in it before it reads the audio. Save as repro.py, then run from an empty directory:

PYTHONPATH=<FunASR>/runtime/python/onnxruntime python repro.py onnx
PYTHONPATH=<FunASR>/runtime/python/libtorch python repro.py torch
import importlib
import sys

backend = sys.argv[1]  # "onnx" or "torch"
module = importlib.import_module("funasr_" + backend + ".paraformer_bin")
tokens = ["<blank>", "<s>", "</s>"] + list("阿里巴达摩院语音实验室魔搭") + ["<unk>"]

for name in ("ContextualParaformer", "SeacoParaformer"):
    cls = getattr(module, name)
    model = cls.__new__(cls)  # skip loading model files: proc_hotword only needs the vocabulary
    model.vocab = {token: index for index, token in enumerate(tokens)}
    print(f"funasr_{backend}.{name}")
    for hotwords in ["魔搭 达摩院", "魔搭  达摩院", "", "魔搭 阿里巴巴达摩院语音实验室"]:
        try:
            matrix, lengths = model.proc_hotword(hotwords)
        except ValueError as error:
            print(f"  {hotwords!r}: ValueError: {error}")
            continue
        rows = [[int(i) for i in row if i] for row in matrix.tolist()]
        print(f"  {hotwords!r}: ids {rows}, embedding positions {lengths.tolist()}")
    try:
        model("audio.wav", "魔搭 阿里巴巴达摩院语音实验室")
    except ValueError as error:
        print(f"  model('audio.wav', '魔搭 阿里巴巴达摩院语音实验室'): ValueError: {error}")

Output (SeacoParaformer and both funasr_torch classes print the same lines):

funasr_onnx.ContextualParaformer
  '魔搭 达摩院': ids [[14, 15], [6, 7, 8], [1]], embedding positions [1, 2, 0]
  '魔搭  达摩院': ids [[14, 15], [], [6, 7, 8], [1]], embedding positions [1, -1, 2, 0]
  '': ids [[], [1]], embedding positions [-1, 0]
  '魔搭 阿里巴巴达摩院语音实验室': ValueError: could not broadcast input array from shape (12,) into shape (10,)
  model('audio.wav', '魔搭 阿里巴巴达摩院语音实验室'): ValueError: could not broadcast input array from shape (12,) into shape (10,)

The ids are each hotword's row without its padding zeros, and <s> (id 1) is the row that proc_hotword appends. The embedding positions are where __call__ reads each hotword's embedding.

Expected, as in the C++ runtime: a longer hotword keeps its first 10 characters, and empty hotwords are skipped, so '魔搭 达摩院' gives the same input as '魔搭 达摩院', and '' gives only <s>.

Environment: Windows 11, Python 3.11.17, numpy 2.4.6, torch 2.10.0+cpu, sources from main.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions