---
title: conformer
canonical_url: "https://www.modelscope.cn/models/AIBS/conformer"
md_url: "https://www.modelscope.cn/models/AIBS/conformer.md"
repository: AIBS/conformer
last_updated: 2026-04-08
pipeline_tag: auto-speech-recognition
tasks:
  - auto-speech-recognition
library_name:
  - onnx
  - pytorch
frameworks:
  - Pytorch
downloads: 2
stars: 0
---

# conformer

> conformer - AIBS 在 ModelScope 开源的模型。asr任务下conformer语音模型在icraft上的适配情况，开发工程基于funasr工具包

- **Repository**: AIBS/conformer
- **Tasks**: auto-speech-recognition
- **Downloads**: 2
- **Stars**: 0
- **Last updated**: 2026-04-08

Source: https://www.modelscope.cn/models/AIBS/conformer

---

## 模型简介

2020年，Google在Transformer结构的基础上提出了Conformer（convolution-augmented transformer for speech recognition）

encoder:

![img](https://ucnb4916m9po.feishu.cn/space/api/box/stream/download/asynccode/?code=M2U0MzI2ZjMxODAxNGExMTBhNmI2YmNlOGVlYWI3YTVfMDRxYWN1WWwzc1pNVVl5Q3oyODFVNjRhNHNuUmF1OFBfVG9rZW46T2didGJXY1NYb002TTh4SU9xMmNkbXByblFlXzE3NTkxMTUyNjE6MTc1OTExODg2MV9WNA)

Decoder: We use a single-LSTM-layer decoder in all our models. 

参数量

![img](https://ucnb4916m9po.feishu.cn/space/api/box/stream/download/asynccode/?code=ZDQxNDMwNzFkZjlhOTk2OTQxOGQ4ZmI0ZmMyOWUwZjlfbURocExqdHVnbHZVYm5KcVZLckZkZ1BqUXR5SHVGVmJfVG9rZW46UVVFRWI2bGtVb0lVTUF4dG1oT2NxY3Fmbk5oXzE3NTkxMTUyNjE6MTc1OTExODg2MV9WNA)

数据集评估

| model     | dev(CER%) | test(CER%) | RTF  |
| --------- | --------- | ---------- | ---- |
| Conformer | 4.42      | 4.87       | 0.21 |

## 模型推断

同sensevoice那一套流程，但是不支持中文，只支持英文。

```Python
# 基于funasr的推断简化版，这里推断结果与modelscope一致
# model = AutoModel(model='iic/SenseVoiceSmall')
model = AutoModel(model='iic/speech_conformer_asr-en-16k-vocab4199-pytorch', device="cpu")
# res = model.generate(input='./example/en.mp3')
res = model.generate(input='./example/asr_example.wav')
# res = model.generate(input='./example/asr_example_zh.wav')
print(res)
```

'./example/en.mp3'推断输出，结果正确。

> [{'key': 'en', 'token': ['the', 'tri@@', 'bal', 'chi@@', 'ef@@', 'tain', 'called', 'for', 'the', 'boy', 'and', 'presented', 'him', 'with', 'fifty', 'pieces', 'of', 'gold'], 'text': 'the tribal chieftain called for the boy and presented him with fifty pieces of gold'}]

> 酋长召唤了那个男孩，并给了他五十枚金币。

## 模型导出

### encoder部分

在funasr->models->transformer->model.py中Transformer类中的inference函数导出模型encoder部分

```Python
class Transformer(nn.Module):
    def inference():
        ...
      # Encoder
        encoder_out, encoder_out_lens = self.encode(speech, speech_lengths)
        # lmy: for conformer export onnx
        print("exporting onnx...")
        torch.onnx.export(self.encoder,(speech,speech_lengths),'./conformer.onnx',opset_version=17)
        import numpy as np
        input_speech = speech.numpy().astype(np.float32)
        input_speech_lengths = speech_lengths.numpy().astype(np.float32)
        input_speech.tofile('./speech.ftmp')
        input_speech_lengths.tofile('./speech_lengths.ftmp')
```

> encode输出大小torch.Size([1, 120, 512])

> encode输入torch.Size([1, 120, 560])

> encode输入lens torch.Size([1])

### decoder部分

说明：论文中说解码器是一层LSTM，但代码中的解码过程主要依赖于“束搜索”（beam search）算法。

```Python
        nbest_hyps = self.beam_search(
            x=encoder_out[0],
            maxlenratio=kwargs.get("maxlenratio", 0.0),
            minlenratio=kwargs.get("minlenratio", 0.0),
        )
```

代码说明：self.beam_search 方法会根据编码器的输出（encoder_out[0]），以及最大/最小长度比例（maxlenratio、minlenratio），生成一组候选的解码结果（nbest_hyps）。束搜索是一种在序列生成任务中常用的解码策略，可以在每一步保留概率最高的若干条路径，从而获得更优的输出序列。得到的 nbest_hyps 是一个包含多个假设（hypothesis）的列表，每个假设都代表一种可能的解码结果。代码只保留前 self.nbest 个最优假设。对每个 batch 的数据，遍历所有 nbest 假设，取出每个假设的输出序列 hyp.yseq，去掉起始符（sos）、终止符（eos）和 blank（通常为0），只保留有效的 token id。这些 token id 会通过 tokenizer.ids2tokens 转换为实际的 token，再通过 tokenizer.tokens2text 转换为文本。最后还会经过后处理（如去除多余空格、符号等），得到最终的解码文本。

这个init_beam_search算法主要是从transformer decoder 和ctc这两个解码器进行评分并筛选。

模型配置文件中配置了decoder参数

```YAML
# decoder
decoder: TransformerDecoder
decoder_conf:
    attention_heads: 16
    linear_units: 1536
    num_blocks: 16
    dropout_rate: 0.1
    positional_dropout_rate: 0.1
    self_attention_dropout_rate: 0.0
    src_attention_dropout_rate: 0.0
```

## 模型编译

### encoder部分

Where 算子不支持

不支持定位funasr->models->transformer->attention.py(同sensevoicesmall)

```Python
class MultiHeadedAttention(nn.Module):
    def Forward_attention(self,walue,scores,mask):
        ...
        if mask is not None:

            attn = torch.softmax(scores,dim=-1)

            # # lmy note: for onnx export
            # mask = mask.unsqueeze(1).eq(0)  # (batch, 1, *, time2)

            # min_value = -float(
            #     "inf"
            # )  # min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min)
            # scores = scores.masked_fill(mask, min_value)
            # attn = torch.softmax(scores, dim=-1).masked_fill(
            #     mask, 0.0
            # )  # (batch, head, time1, time2)
            # # lmy note end
        else:
            attn = torch.softmax(scores, dim=-1)  # (batch, head, time1, time2)
```

修改后成功导出模型encode部分，输入为[1,120,560]耗时为114.767ms

![img](https://ucnb4916m9po.feishu.cn/space/api/box/stream/download/asynccode/?code=N2Q5MmQxYjdiZjIxYTIyM2Y5NTc3Mzg0OWZkOGNiMzRfZHYzU2pNSUJwcnVWR01pdlVQUFl6cFlyNEhMYUppNnBfVG9rZW46UGM2RGI2QTUzb09HaFl4eW8zcGM2NG1VbnBjXzE3NTkxMTUyNjE6MTc1OTExODg2MV9WNA)

### decoder部分

BeamSearch

BeamSearch 是 FunASR 里用于做解码的类，它会用你给定的参数（如 beam_size、权重、打分器、sos/eos、词表等）来做语音识别的束搜索推理。

beam_size：束宽，决定每步保留多少条候选路径。

weights：各个打分器（如 CTC、decoder、LM、ngram、length_bonus）的权重。

scorers：包含 CTC、decoder、长度奖励等打分器对象。

sos/eos：起始和终止符号的 id。

vocab_size、token_list：词表大小和内容。

pre_beam_score_key：控制 CTC/Attention 混合解码的策略。

为什么不能直接导出 ONNX 或 trace？

BeamSearch 不是标准的 nn.Module，内部有大量 Python 控制流、list、dict、对象操作，甚至可能有 for/while/if 等原生逻辑。这些都不能被 torch.jit.trace 或 torch.onnx.export 支持。

目前 FunASR 的 BeamSearch 主要是 Python 逻辑，不适合直接导出。

这代码里的decoder是给ctc和transformer_decoder两部分初始化分数分别为0.5，我为了方便，不动态选择decoder，**直接指定ctc**。参照sensevoicesmall，ctc是可以导出且编译的。

```Python
        # lmy modified decoder beam search
        ctc_logp = self.ctc.softmax(encoder_out)
        x = ctc_logp[0, : encoder_out_lens[0].item(), :]
        yseq = x.argmax(dim=-1)
        yseq = torch.unique_consecutive(yseq, dim=-1)
        # 去掉 blank 和重复
        prev = None
        output_ids = []
        for idx in yseq:
            if idx != self.blank_id and idx != prev:
                output_ids.append(idx)
            prev = idx
        # 转成文本
        token = tokenizer.ids2tokens(output_ids)
        text = tokenizer.tokens2text(token)
        text_postprocessed, _ = postprocess_utils.sentence_postprocess(token)
        result_i = {"key": key[0], "token": token, "text": text_postprocessed}
        results = [result_i]
        return results, meta_data
```

两个demo结果如下

'./example/en.mp3'推断输出，结果正确。

> [{'key': 'en', 'token': ['the', 'tri@@', 'bal', 'chi@@', 'ef@@', 'tain', 'called', 'for', 'the', 'boy', 'and', 'presented', 'him', 'with', 'fifty', 'pieces', 'of', 'gold'], 'text': 'the tribal chieftain called for the boy and presented him with fifty pieces of gold'}]

> 酋长召唤了那个男孩，并给了他五十枚金币。

#### 您可以通过如下git clone命令，或者ModelScope SDK来下载模型

SDK下载
```bash
#安装ModelScope
pip install modelscope
```
```python
#SDK模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('limengying/conformer')
```
Git下载
```
#Git模型下载
git clone https://www.modelscope.cn/limengying/conformer.git
```
