Fun-ASR-MLT-Nano-2512实战教程:Python API批量处理目录下所有MP3文件

你是不是也遇到过这样的烦恼?手头有一大堆会议录音、访谈音频或者课程录像,一个个点开去转文字,费时又费力。或者作为一个开发者,想给自己的应用加上语音转文字功能,却不知道从何下手。

今天,我就带你用Fun-ASR-MLT-Nano-2512这个强大的语音识别模型,写一个Python脚本,一次性把整个文件夹里的MP3文件全部转成文字。整个过程就像把一堆食材倒进料理机,出来就是切好的菜,简单又高效。

Fun-ASR-MLT-Nano-2512是阿里通义实验室出的一个多语言语音识别模型,别看它名字里带个“Nano”,能力可不小。它支持31种语言,包括中文、英文、日文、韩文,甚至粤语都能识别,对于常见的会议录音、视频字幕生成这些场景,准确率相当不错。

我们这篇教程的目标很明确:不搞复杂的理论,直接上手写代码,让你在10分钟内拥有一个能批量处理音频的得力工具。

1. 环境准备:给你的电脑装上“耳朵”

工欲善其事,必先利其器。首先,我们得确保电脑环境准备好了。别担心,步骤很简单。

1.1 检查基础环境

这个模型推荐在Linux系统上跑,比如Ubuntu。如果你用的是Windows,我强烈建议你安装一个WSL2(Windows Subsystem for Linux),这能省去很多兼容性麻烦。Mac用户通常可以直接使用。

打开你的终端(命令行),依次输入下面命令,看看环境是否满足:

# 查看Python版本,需要3.8或以上
python3 --version

# 查看是否有GPU(可选,有GPU会快很多)
nvidia-smi

如果看到Python版本号大于等于3.8,那第一步就妥了。如果看到GPU信息,那恭喜你,处理速度会飞起。

1.2 安装必要的软件包

我们需要安装两个核心的东西:一个是Python包管理工具pip,另一个是处理音频必需的ffmpeg

# 更新软件包列表(Ubuntu/Debian系统)
sudo apt-get update

# 安装ffmpeg,这是处理音频视频的瑞士军刀
sudo apt-get install -y ffmpeg

# 确保pip是最新版本
python3 -m pip install --upgrade pip

安装完这些,基础环境就搭建好了。

2. 获取并部署Fun-ASR模型

环境好了,接下来把“主角”——语音识别模型请过来。

2.1 下载模型文件

最方便的方法是从Hugging Face模型库直接下载。我们创建一个专门的项目文件夹来存放一切。

# 创建一个项目文件夹
mkdir funasr_batch_project
cd funasr_batch_project

# 使用git克隆模型仓库(如果git clone慢,可以手动下载ZIP包)
git clone https://huggingface.co/FunAudioLLM/Fun-ASR-MLT-Nano-2512

如果网络不太顺畅,你也可以直接访问Hugging Face模型页面,点击“Files and versions”标签页,手动下载所有文件,然后放到你创建的Fun-ASR-MLT-Nano-2512文件夹里。

下载完成后,你的文件夹结构应该看起来像这样:

funasr_batch_project/
└── Fun-ASR-MLT-Nano-2512/
    ├── model.pt                 # 核心模型文件,大约2GB
    ├── model.py                 # 模型定义文件(已包含重要修复)
    ├── config.yaml              # 配置文件
    ├── requirements.txt         # Python依赖列表
    └── ...                      # 其他配置文件

2.2 安装Python依赖

模型下载好了,它需要一些特定的Python库才能运行。这些依赖都写在requirements.txt文件里了。

# 进入模型目录
cd Fun-ASR-MLT-Nano-2512

# 安装所有必需的Python库
pip install -r requirements.txt

这个过程可能会花几分钟,因为它要下载和安装一些机器学习相关的库,比如torch(PyTorch深度学习框架)。泡杯茶稍等一下就好。

一个重要提示:项目里的model.py文件已经包含了一个关键修复,解决了一个可能导致推理失败的问题。所以你直接使用就行,不用担心。

3. 编写批量处理脚本:一键转换的核心

好了,最核心的部分来了——写一个Python脚本。这个脚本要做三件事:1. 加载模型;2. 遍历文件夹找到所有MP3文件;3. 逐个识别并把结果保存下来。

在你的项目根目录(funasr_batch_project)下,创建一个新文件,命名为batch_transcribe.py

3.1 脚本基础框架

我们先搭建脚本的骨架,把主要流程定下来。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Fun-ASR-MLT-Nano-2512 批量语音转文字脚本
作者:by113小贝
功能:自动扫描指定目录下的所有MP3文件,并转换为文本
"""

import os
import sys
import argparse
import time
import json
from pathlib import Path
from typing import List, Dict

def find_mp3_files(directory: str) -> List[str]:
    """查找目录下所有的MP3文件"""
    mp3_files = []
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.lower().endswith('.mp3'):
                full_path = os.path.join(root, file)
                mp3_files.append(full_path)
    return sorted(mp3_files)  # 排序一下,处理顺序固定

def transcribe_audio(model, audio_path: str, language: str = "中文") -> Dict:
    """识别单个音频文件"""
    try:
        # 这里是调用模型的核心代码,后面会填充
        pass
    except Exception as e:
        print(f"  识别失败: {e}")
        return {"file": audio_path, "text": "", "error": str(e)}

def save_results(results: List[Dict], output_file: str):
    """保存识别结果到文件"""
    # 这里写保存逻辑,后面填充
    pass

def main():
    """主函数"""
    # 这里写主逻辑,后面填充
    pass

if __name__ == "__main__":
    main()

这个框架定义了四个主要函数,结构很清晰。接下来我们往里面填充血肉。

3.2 填充核心识别功能

现在来写最关键的transcribe_audio函数,这里我们要调用Fun-ASR模型。

首先,在脚本最开头,我们需要导入模型类。注意:因为Fun-ASR-MLT-Nano-2512是一个较新的模型,我们使用AutoModel并指定本地路径来加载。

# 在文件开头的import部分添加
from funasr import AutoModel

# 然后修改 transcribe_audio 函数
def transcribe_audio(model, audio_path: str, language: str = "中文") -> Dict:
    """识别单个音频文件"""
    print(f"  正在处理: {os.path.basename(audio_path)}")
    
    try:
        # 调用模型进行识别
        # 注意:input参数需要传入一个列表,即使只有一个文件
        result = model.generate(
            input=[audio_path],      # 音频文件路径列表
            cache={},                # 缓存,留空即可
            batch_size=1,            # 批量大小,这里一次处理一个
            language=language,       # 识别语言
            itn=True                 # 是否进行逆文本归一化(比如把“123”转成“一百二十三”)
        )
        
        # 提取识别出的文本
        # result是一个列表,里面包含字典
        if result and len(result) > 0:
            text = result[0].get("text", "")
            return {
                "file": audio_path,
                "text": text,
                "language": language,
                "status": "success"
            }
        else:
            return {
                "file": audio_path,
                "text": "",
                "language": language,
                "status": "no_result"
            }
            
    except Exception as e:
        print(f"  识别失败: {e}")
        return {
            "file": audio_path,
            "text": "",
            "language": language,
            "status": "error",
            "error": str(e)
        }

3.3 完善结果保存功能

识别出来的文字需要保存下来,我们设计两种格式:一个是纯文本(.txt),方便阅读;一个是JSON格式(.json),方便程序进一步处理。

def save_results(results: List[Dict], output_dir: str, base_name: str = "transcription"):
    """保存识别结果到文件"""
    
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    
    # 1. 保存为纯文本文件
    txt_file = os.path.join(output_dir, f"{base_name}.txt")
    with open(txt_file, 'w', encoding='utf-8') as f:
        f.write(f"批量语音识别结果\n")
        f.write(f"生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"=" * 50 + "\n\n")
        
        for i, item in enumerate(results, 1):
            f.write(f"{i}. 文件: {os.path.basename(item['file'])}\n")
            f.write(f"   语言: {item.get('language', 'N/A')}\n")
            f.write(f"   状态: {item.get('status', 'N/A')}\n")
            f.write(f"   文本:\n")
            
            text = item.get('text', '')
            # 如果文本太长,适当换行
            if len(text) > 80:
                for j in range(0, len(text), 80):
                    f.write(f"   {text[j:j+80]}\n")
            else:
                f.write(f"   {text}\n")
            
            f.write(f"\n{'-' * 40}\n\n")
    
    print(f"✓ 文本结果已保存至: {txt_file}")
    
    # 2. 保存为JSON文件(结构化数据,方便程序处理)
    json_file = os.path.join(output_dir, f"{base_name}.json")
    with open(json_file, 'w', encoding='utf-8') as f:
        json.dump({
            "metadata": {
                "model": "Fun-ASR-MLT-Nano-2512",
                "generated_at": time.strftime('%Y-%m-%d %H:%M:%S'),
                "total_files": len(results)
            },
            "results": results
        }, f, ensure_ascii=False, indent=2)
    
    print(f"✓ JSON结果已保存至: {json_file}")
    
    # 3. 为每个音频文件单独保存一个TXT文件
    for item in results:
        if item.get('status') == 'success' and item.get('text'):
            audio_name = os.path.splitext(os.path.basename(item['file']))[0]
            single_file = os.path.join(output_dir, f"{audio_name}.txt")
            with open(single_file, 'w', encoding='utf-8') as f:
                f.write(item['text'])

3.4 完成主函数逻辑

最后,我们把所有部分串联起来,形成一个完整的程序。

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='批量语音识别工具')
    parser.add_argument('-i', '--input', required=True, help='包含MP3文件的输入目录')
    parser.add_argument('-o', '--output', default='./output', help='输出目录(默认:./output)')
    parser.add_argument('-l', '--language', default='中文', help='识别语言(默认:中文)')
    parser.add_argument('-m', '--model_path', default='./Fun-ASR-MLT-Nano-2512', 
                       help='模型路径(默认:./Fun-ASR-MLT-Nano-2512)')
    
    args = parser.parse_args()
    
    # 检查输入目录是否存在
    if not os.path.isdir(args.input):
        print(f"错误:输入目录不存在 - {args.input}")
        sys.exit(1)
    
    print("=" * 60)
    print("Fun-ASR-MLT-Nano-2512 批量语音识别工具")
    print("=" * 60)
    print(f"输入目录: {args.input}")
    print(f"输出目录: {args.output}")
    print(f"识别语言: {args.language}")
    print(f"模型路径: {args.model_path}")
    print("-" * 60)
    
    # 1. 查找所有MP3文件
    print("步骤1: 扫描MP3文件...")
    mp3_files = find_mp3_files(args.input)
    
    if not mp3_files:
        print(f"在目录 {args.input} 中未找到MP3文件")
        sys.exit(0)
    
    print(f"找到 {len(mp3_files)} 个MP3文件")
    for i, f in enumerate(mp3_files[:5], 1):  # 只显示前5个
        print(f"  {i}. {os.path.basename(f)}")
    if len(mp3_files) > 5:
        print(f"  ... 以及另外 {len(mp3_files) - 5} 个文件")
    
    # 2. 加载模型(这一步可能较慢,因为要加载2GB的模型)
    print(f"\n步骤2: 加载语音识别模型...")
    print("  首次加载可能需要30-60秒,请耐心等待...")
    
    start_time = time.time()
    try:
        # 关键:从这里加载模型
        model = AutoModel(
            model=args.model_path,      # 模型所在目录
            trust_remote_code=True,     # 信任远程代码(因为用了自定义模型)
            device="cuda:0"             # 使用GPU,如果没有GPU改为"cpu"
        )
        load_time = time.time() - start_time
        print(f"✓ 模型加载成功!耗时 {load_time:.1f} 秒")
    except Exception as e:
        print(f"✗ 模型加载失败: {e}")
        print("提示:如果没有GPU,请将 device 参数改为 'cpu'")
        sys.exit(1)
    
    # 3. 逐个处理音频文件
    print(f"\n步骤3: 开始识别处理...")
    all_results = []
    
    for i, audio_file in enumerate(mp3_files, 1):
        print(f"\n[{i}/{len(mp3_files)}] ", end="")
        
        file_start = time.time()
        result = transcribe_audio(model, audio_file, args.language)
        file_time = time.time() - file_start
        
        result["processing_time"] = round(file_time, 2)
        all_results.append(result)
        
        if result.get('status') == 'success':
            text_preview = result['text'][:50] + "..." if len(result['text']) > 50 else result['text']
            print(f"  识别成功 ({file_time:.1f}s): {text_preview}")
        else:
            print(f"  识别失败")
    
    # 4. 保存结果
    print(f"\n步骤4: 保存识别结果...")
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    save_results(all_results, args.output, f"transcription_{timestamp}")
    
    # 5. 统计信息
    print(f"\n步骤5: 生成处理报告...")
    success_count = sum(1 for r in all_results if r.get('status') == 'success')
    total_time = sum(r.get('processing_time', 0) for r in all_results)
    
    print(f"\n{'=' * 60}")
    print("处理完成!")
    print(f"{'=' * 60}")
    print(f"总计处理文件: {len(mp3_files)} 个")
    print(f"成功识别: {success_count} 个")
    print(f"总耗时: {total_time:.1f} 秒")
    print(f"平均每个文件: {total_time/len(mp3_files):.1f} 秒")
    print(f"输出目录: {os.path.abspath(args.output)}")
    print(f"{'=' * 60}")

3.5 完整的脚本代码

把上面所有代码段组合起来,就是完整的batch_transcribe.py脚本了。你可以直接复制下面的完整代码使用。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Fun-ASR-MLT-Nano-2512 批量语音识别脚本
作者:by113小贝
功能:自动扫描指定目录下的所有MP3文件,并转换为文本
"""

import os
import sys
import argparse
import time
import json
from pathlib import Path
from typing import List, Dict
from funasr import AutoModel

def find_mp3_files(directory: str) -> List[str]:
    """查找目录下所有的MP3文件"""
    mp3_files = []
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.lower().endswith('.mp3'):
                full_path = os.path.join(root, file)
                mp3_files.append(full_path)
    return sorted(mp3_files)

def transcribe_audio(model, audio_path: str, language: str = "中文") -> Dict:
    """识别单个音频文件"""
    print(f"  正在处理: {os.path.basename(audio_path)}")
    
    try:
        result = model.generate(
            input=[audio_path],
            cache={},
            batch_size=1,
            language=language,
            itn=True
        )
        
        if result and len(result) > 0:
            text = result[0].get("text", "")
            return {
                "file": audio_path,
                "text": text,
                "language": language,
                "status": "success"
            }
        else:
            return {
                "file": audio_path,
                "text": "",
                "language": language,
                "status": "no_result"
            }
            
    except Exception as e:
        print(f"  识别失败: {e}")
        return {
            "file": audio_path,
            "text": "",
            "language": language,
            "status": "error",
            "error": str(e)
        }

def save_results(results: List[Dict], output_dir: str, base_name: str = "transcription"):
    """保存识别结果到文件"""
    os.makedirs(output_dir, exist_ok=True)
    
    txt_file = os.path.join(output_dir, f"{base_name}.txt")
    with open(txt_file, 'w', encoding='utf-8') as f:
        f.write(f"批量语音识别结果\n")
        f.write(f"生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"=" * 50 + "\n\n")
        
        for i, item in enumerate(results, 1):
            f.write(f"{i}. 文件: {os.path.basename(item['file'])}\n")
            f.write(f"   语言: {item.get('language', 'N/A')}\n")
            f.write(f"   状态: {item.get('status', 'N/A')}\n")
            f.write(f"   文本:\n")
            
            text = item.get('text', '')
            if len(text) > 80:
                for j in range(0, len(text), 80):
                    f.write(f"   {text[j:j+80]}\n")
            else:
                f.write(f"   {text}\n")
            
            f.write(f"\n{'-' * 40}\n\n")
    
    print(f"✓ 文本结果已保存至: {txt_file}")
    
    json_file = os.path.join(output_dir, f"{base_name}.json")
    with open(json_file, 'w', encoding='utf-8') as f:
        json.dump({
            "metadata": {
                "model": "Fun-ASR-MLT-Nano-2512",
                "generated_at": time.strftime('%Y-%m-%d %H:%M:%S'),
                "total_files": len(results)
            },
            "results": results
        }, f, ensure_ascii=False, indent=2)
    
    print(f"✓ JSON结果已保存至: {json_file}")
    
    for item in results:
        if item.get('status') == 'success' and item.get('text'):
            audio_name = os.path.splitext(os.path.basename(item['file']))[0]
            single_file = os.path.join(output_dir, f"{audio_name}.txt")
            with open(single_file, 'w', encoding='utf-8') as f:
                f.write(item['text'])

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='批量语音识别工具')
    parser.add_argument('-i', '--input', required=True, help='包含MP3文件的输入目录')
    parser.add_argument('-o', '--output', default='./output', help='输出目录(默认:./output)')
    parser.add_argument('-l', '--language', default='中文', help='识别语言(默认:中文)')
    parser.add_argument('-m', '--model_path', default='./Fun-ASR-MLT-Nano-2512', 
                       help='模型路径(默认:./Fun-ASR-MLT-Nano-2512)')
    
    args = parser.parse_args()
    
    if not os.path.isdir(args.input):
        print(f"错误:输入目录不存在 - {args.input}")
        sys.exit(1)
    
    print("=" * 60)
    print("Fun-ASR-MLT-Nano-2512 批量语音识别工具")
    print("=" * 60)
    print(f"输入目录: {args.input}")
    print(f"输出目录: {args.output}")
    print(f"识别语言: {args.language}")
    print(f"模型路径: {args.model_path}")
    print("-" * 60)
    
    print("步骤1: 扫描MP3文件...")
    mp3_files = find_mp3_files(args.input)
    
    if not mp3_files:
        print(f"在目录 {args.input} 中未找到MP3文件")
        sys.exit(0)
    
    print(f"找到 {len(mp3_files)} 个MP3文件")
    for i, f in enumerate(mp3_files[:5], 1):
        print(f"  {i}. {os.path.basename(f)}")
    if len(mp3_files) > 5:
        print(f"  ... 以及另外 {len(mp3_files) - 5} 个文件")
    
    print(f"\n步骤2: 加载语音识别模型...")
    print("  首次加载可能需要30-60秒,请耐心等待...")
    
    start_time = time.time()
    try:
        model = AutoModel(
            model=args.model_path,
            trust_remote_code=True,
            device="cuda:0"
        )
        load_time = time.time() - start_time
        print(f"✓ 模型加载成功!耗时 {load_time:.1f} 秒")
    except Exception as e:
        print(f"✗ 模型加载失败: {e}")
        print("提示:如果没有GPU,请将 device 参数改为 'cpu'")
        sys.exit(1)
    
    print(f"\n步骤3: 开始识别处理...")
    all_results = []
    
    for i, audio_file in enumerate(mp3_files, 1):
        print(f"\n[{i}/{len(mp3_files)}] ", end="")
        
        file_start = time.time()
        result = transcribe_audio(model, audio_file, args.language)
        file_time = time.time() - file_start
        
        result["processing_time"] = round(file_time, 2)
        all_results.append(result)
        
        if result.get('status') == 'success':
            text_preview = result['text'][:50] + "..." if len(result['text']) > 50 else result['text']
            print(f"  识别成功 ({file_time:.1f}s): {text_preview}")
        else:
            print(f"  识别失败")
    
    print(f"\n步骤4: 保存识别结果...")
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    save_results(all_results, args.output, f"transcription_{timestamp}")
    
    print(f"\n步骤5: 生成处理报告...")
    success_count = sum(1 for r in all_results if r.get('status') == 'success')
    total_time = sum(r.get('processing_time', 0) for r in all_results)
    
    print(f"\n{'=' * 60}")
    print("处理完成!")
    print(f"{'=' * 60}")
    print(f"总计处理文件: {len(mp3_files)} 个")
    print(f"成功识别: {success_count} 个")
    print(f"总耗时: {total_time:.1f} 秒")
    print(f"平均每个文件: {total_time/len(mp3_files):.1f} 秒")
    print(f"输出目录: {os.path.abspath(args.output)}")
    print(f"{'=' * 60}")

if __name__ == "__main__":
    main()

4. 运行与实战:让脚本动起来

脚本写好了,现在让我们实际运行一下,看看效果如何。

4.1 准备测试音频

首先,我们需要一些MP3文件来测试。你可以用自己的录音,或者用模型自带的示例音频。

# 进入项目目录
cd ~/funasr_batch_project

# 创建一个测试目录,并放入一些MP3文件
mkdir -p test_audios

# 复制模型自带的示例音频到测试目录(如果没有自己的音频)
cp Fun-ASR-MLT-Nano-2512/example/*.mp3 test_audios/

# 看看复制了哪些文件
ls -la test_audios/

你应该能看到类似这样的文件:

  • zh.mp3(中文示例)
  • en.mp3(英文示例)
  • ja.mp3(日文示例)
  • 等等

4.2 运行批量识别脚本

现在,运行我们的脚本处理这些测试音频。

# 基本用法:处理test_audios目录下的所有MP3文件
python batch_transcribe.py -i test_audios -o results

# 如果你想指定识别语言为英文
python batch_transcribe.py -i test_audios -o results -l "英文"

# 如果你想指定模型路径(如果不在当前目录)
python batch_transcribe.py -i test_audios -o results -m "/path/to/your/Fun-ASR-MLT-Nano-2512"

运行后,你会看到类似这样的输出:

============================================================
Fun-ASR-MLT-Nano-2512 批量语音识别工具
============================================================
输入目录: test_audios
输出目录: results
识别语言: 中文
模型路径: ./Fun-ASR-MLT-Nano-2512
------------------------------------------------------------
步骤1: 扫描MP3文件...
找到 5 个MP3文件
  1. zh.mp3
  2. en.mp3
  3. ja.mp3
  4. ko.mp3
  5. yue.mp3

步骤2: 加载语音识别模型...
  首次加载可能需要30-60秒,请耐心等待...
✓ 模型加载成功!耗时 42.3 秒

步骤3: 开始识别处理...

[1/5]   正在处理: zh.mp3
  识别成功 (1.2s): 欢迎使用阿里巴巴达摩院语音实验室...

[2/5]   正在处理: en.mp3
  识别成功 (1.1s): Welcome to Alibaba DAMO Academy...

...

4.3 查看识别结果

处理完成后,脚本会在results目录下生成多个文件:

# 查看输出目录
ls -la results/

# 查看汇总的文本结果
cat results/transcription_20250114_143022.txt

# 查看JSON格式的结构化结果
cat results/transcription_20250114_143022.json | head -50

每个音频文件也会有一个单独的TXT文件,比如zh.txten.txt等,里面就是纯文本的识别结果。

5. 进阶技巧与问题排查

基本的批量处理已经实现了,但实际使用中你可能会遇到一些特殊情况。这里分享几个实用技巧。

5.1 处理长音频文件

如果你有很长的音频(比如1小时以上的会议录音),直接处理可能会内存不足。这时候可以分段处理:

# 这是一个简化的分段处理思路,你可以集成到主脚本中
def process_long_audio(model, audio_path, chunk_duration=300):
    """将长音频分割成小段处理"""
    import librosa
    
    # 加载音频
    y, sr = librosa.load(audio_path, sr=16000)
    total_duration = len(y) / sr
    
    all_text = []
    for start in range(0, int(total_duration), chunk_duration):
        end = min(start + chunk_duration, total_duration)
        chunk = y[int(start*sr):int(end*sr)]
        
        # 保存临时片段
        temp_file = f"temp_chunk_{start}.wav"
        sf.write(temp_file, chunk, sr)
        
        # 识别片段
        result = model.generate(input=[temp_file], ...)
        if result:
            all_text.append(result[0]["text"])
        
        # 清理临时文件
        os.remove(temp_file)
    
    return " ".join(all_text)

5.2 支持更多音频格式

我们的脚本目前只处理MP3,但Fun-ASR其实支持WAV、M4A、FLAC等多种格式。修改find_mp3_files函数即可:

def find_audio_files(directory: str) -> List[str]:
    """查找目录下所有的音频文件"""
    audio_extensions = ['.mp3', '.wav', '.m4a', '.flac', '.ogg', '.aac']
    audio_files = []
    
    for root, dirs, files in os.walk(directory):
        for file in files:
            if any(file.lower().endswith(ext) for ext in audio_extensions):
                full_path = os.path.join(root, file)
                audio_files.append(full_path)
    
    return sorted(audio_files)

5.3 常见问题与解决

问题1:模型加载太慢

  • 原因:首次加载需要将2GB模型读入内存
  • 解决:这是正常现象,首次加载后,只要不重启Python进程,后续调用会很快

问题2:识别结果有误

  • 原因:音频质量差、背景噪音大、方言口音重
  • 解决:尝试预处理音频(降噪、归一化音量),或明确指定语言参数

问题3:GPU内存不足

  • 解决:在加载模型时使用device="cpu",或者减少batch_size
# 使用CPU而不是GPU
model = AutoModel(
    model=args.model_path,
    trust_remote_code=True,
    device="cpu"  # 改为CPU
)

问题4:某些文件识别失败

  • 解决:脚本已经包含错误处理,失败的文件会在结果中标记,不会影响其他文件处理

6. 总结与扩展

通过这篇教程,我们完成了一个完整的批量语音识别工具。从环境搭建、模型部署到脚本编写和实际运行,每一步都有详细的代码和说明。

回顾一下我们实现的核心功能:

  1. 自动扫描目录:递归查找所有MP3文件
  2. 批量识别处理:使用Fun-ASR模型逐个转换
  3. 多格式输出:同时生成汇总文本、JSON和单个文件
  4. 完整日志:实时显示处理进度和结果预览
  5. 错误处理:单个文件失败不影响整体流程

这个脚本可以直接用在很多实际场景中:

  • 会议记录整理:把每周例会录音批量转文字
  • 视频字幕生成:提取视频中的音频后转字幕
  • 播客内容索引:为播客节目创建文字稿便于搜索
  • 语言学习材料:将外语听力材料转成文字对照学习

如果你想进一步扩展这个工具,可以考虑:

  • 添加进度条显示,让等待更直观
  • 支持并行处理,利用多核CPU加速
  • 集成到Web服务,提供网页上传界面
  • 添加音频预处理功能,自动降噪和音量均衡

最重要的是,你现在有了一个可以实际工作的工具,而不是仅仅停留在理论。下次再遇到一堆音频文件需要转文字时,你只需要运行一行命令,剩下的就交给脚本吧。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐