whisper转录音频文档

whisper转录音频文档

Whisper 是 OpenAI 开发的一个自动语音识别(ASR)系统,它提供了不同大小的预训练模型,模型越大,通常在转录任务中的准确性就越高,但同时也需要更多的计算资源和更长的推理时间。

模型大小与精度

Whisper 一共有 5 种不同大小的模型,按照参数量从小到大依次为 tinybasesmallmedium 和 large,其中 large 又分为 large-v1 和 large-v2large-v2 是目前最新且表现最优的版本。精度上,tiny 模型的准确性最低,而 large-v2 模型的准确性最高。以下是对各个模型的简要介绍:

模型名称参数量英文转录速度多语言转录速度特点
tiny39M~32x~16x速度极快,但精度较低,适用于对速度要求极高且对转录精度要求不高的场景。
base74M~16x~8x速度较快,精度一般,能满足一些基本的转录需求。
small244M~6x~3x速度适中,精度较好,在大多数情况下能提供较为准确的转录结果。
medium769M~2x~1.5x速度相对较慢,但精度较高,能处理一些复杂的语音内容。
large-v11550M1x1x精度很高,但速度最慢,对计算资源要求高。
large-v21550M1x1x在 large-v1 的基础上进一步优化,是目前 Whisper 模型中精度最高的版本。

示例代码

如果你想使用 large-v2 模型进行转录,可以将代码中的 model_name 变量修改为 "large-v2"

import whisper

# 选择 large-v2 模型
model_name = "large-v2"
device = "cuda" if torch.cuda.is_available() else "cpu"

# 加载模型
model = whisper.load_model(model_name, device=device)

# 进行转录
audio_file = "your_audio_file.mp3"
result = model.transcribe(audio_file, language="Japanese", word_timestamps=True)

# 输出转录结果
print(result["text"])Code language: PHP (php)

在实际应用中,你需要根据自己的计算资源、时间限制和对转录精度的要求来选择合适的模型。如果你的计算资源充足,且对转录精度有较高要求,那么可以考虑使用 large-v2 模型;如果对速度要求较高,medium 或更小的模型可能更适合你。

一、 Python 版本问题

openai-whisper 不支持 Python 3.6,你需要将 Python 版本升级到 3.7 及以上。在 CentOS 系统上,你可以按照以下步骤升级 Python:

1.1 安装依赖

sudo yum install -y gcc openssl-devel bzip2-devel libffi-devel zlib-devel

1.2 下载 Python 3.8(这里以 3.8 为例)

wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgzCode language: JavaScript (javascript)

1.3 解压并编译安装

tar -xzf Python-3.8.16.tgz
cd Python-3.8.16
./configure --enable-optimizations ## 如果报错就把--enable-optimizations去掉
make -j$(nproc)
sudo make altinstallCode language: PHP (php)

1.4 验证安装

python3.8 --versionCode language: CSS (css)

2. 使用新的 Python 版本安装 openai-whisper

升级 Python 后,使用新的 Python 版本对应的 pip 来安装 openai-whisper

python3.8 -m pip install --user git+https://github.com/openai/whisper.gitCode language: JavaScript (javascript)

3. 其他可能的问题及解决办法

3.1 镜像源问题

你使用的是阿里云的镜像源,有时镜像源可能同步不及时或者存在其他问题。你可以尝试切换回官方的 PyPI 源:

python3.8 -m pip install --user -i https://pypi.org/simple git+https://github.com/openai/whisper.gitCode language: JavaScript (javascript)

3.2 权限问题

确保你有足够的权限在用户目录下安装包。如果还是遇到权限问题,可以尝试临时使用 sudo 来安装(但要谨慎使用):

sudo python3.8 -m pip install git+https://github.com/openai/whisper.gitCode language: JavaScript (javascript)

通过以上步骤,你应该能够解决安装 openai-whisper 时遇到的问题。

多个脚本被安装到了 /root/.local/bin 目录下,但该目录不在系统的 PATH 环境变量中。这意味着你无法直接在命令行中调用这些脚本,需要手动添加该目录到 PATH 环境变量或者使用完整的路径来调用这些脚本。以下为你提供几种解决方法:

方法一:临时添加目录到 PATH

如果你只是想临时解决这个问题,在当前终端会话中让这些脚本可以被调用,可以在终端中执行以下命令:

export PATH=$PATH:/root/.local/binCode language: JavaScript (javascript)

执行该命令后,在当前终端窗口中就可以直接使用这些脚本了。不过,这种方法只在当前终端会话中有效,关闭终端后设置会失效。

方法二:永久添加目录到 PATH

若你希望每次打开终端时该目录都自动添加到 PATH 中,可以修改用户的环境变量配置文件。对于 root 用户,通常是修改 ~/.bashrc 或 ~/.bash_profile 文件。

修改 ~/.bashrc 文件

nano ~/.bashrc

在文件末尾添加以下内容:

export PATH=$PATH:/root/.local/binCode language: JavaScript (javascript)

保存并退出文件(按 Ctrl + X,然后按 Y 确认保存,最后按 Enter)。接着,使配置文件生效:

source ~/.bashrc

修改 ~/.bash_profile 文件(如果使用的是这个文件)

nano ~/.bash_profile

同样在文件末尾添加 export PATH=$PATH:/root/.local/bin,保存并退出后执行 source ~/.bash_profile 使配置生效。

使用 Python 3.8 对应的 pip 进行安装

使用 python3.8 -m pip 来确保安装操作是针对 Python 3.8 环境的。执行以下命令来安装 PyTorch:

python3.8 -m pip install torch torchvision torchaudioCode language: CSS (css)

方法二:检查 pip 版本对应的 Python 解释器

你可以先查看 pip3 对应的 Python 版本:

pip3 -V

如果显示的 Python 版本是 3.6,那么就说明当前 pip3 关联的是 Python 3.6。你需要使用 Python 3.8 对应的 pip 来安装 PyTorch。可以通过以下方式查看 Python 3.8 对应的 pip 路径:

which python3.8Code language: CSS (css)

假设输出是 /usr/local/bin/python3.8,那么对应的 pip 一般是 /usr/local/bin/pip3.8(路径可能因安装方式不同而有所差异),使用该 pip 来安装 PyTorch:

/usr/local/bin/pip3.8 install torch torchvision torchaudio

检查 GPU 可用性

在解决上述问题后,你可以再次运行 torch_check.py 脚本来检查 GPU 是否可用。以下是一个简单的 torch_check.py 示例代码:

import torch

print(torch.cuda.is_available())Code language: CSS (css)

如果输出为 True,则表示 GPU 可以正常使用;如果仍然为 False,则需要进一步排查问题。

在使用 GPU 进行计算任务(如运行 Whisper 模型转录音频)时,实时查看 GPU 的使用情况有助于你了解 GPU 的负载、显存占用等信息,以便优化任务或排查问题。以下介绍几种常见的实时查看 GPU 使用情况的方法:

1. 使用 nvidia-smi 命令(适用于 NVIDIA GPU)

nvidia-smi 是 NVIDIA 提供的一个命令行工具,可用于监控 NVIDIA GPU 的状态。

基本使用

打开终端,直接输入 nvidia-smi 命令,即可查看当前 GPU 的基本信息,包括 GPU 编号、名称、显存使用情况、GPU 利用率等。

nvidia-smi

示例输出:

Thu Feb  7 17:00:00 2025
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.141.03   Driver Version: 470.141.03   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla P100-PCIE-16GB    Off| 00000000:00:04.0 Off |                    0 |
| N/A   30C    P0    26W / 250W |      5MiB / 16384MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+Code language: PHP (php)

实时监控

若要实时查看 GPU 使用情况,可使用 -l 或 -lms 选项指定刷新间隔。例如,每隔 1 秒刷新一次:

nvidia-smi -l 1

按 Ctrl + C 可停止监控。

2. 使用 gpustat 工具(适用于 NVIDIA GPU)

gpustat 是一个基于 Python 的第三方工具,能以更美观和易读的方式展示 GPU 信息。

安装

使用 pip 安装 gpustat

python3.8 -m pip install gpustatCode language: CSS (css)

使用

在终端输入 gpustat -i 命令,即可实时监控 GPU 使用情况,默认刷新间隔为 1 秒。

gpustat -i

示例输出:

[0] Tesla P100-PCIE-16GB | 30°C,   0 % |    5 / 16384 MB |

示例代码:

import os
import subprocess
import time
import logging
import requests
import urllib.parse
import datetime

# 配置根文件夹
root_folder = "/root/audio_files"

# 配置日志文件路径
log_file = os.path.join(root_folder, "transcription.log")

# 配置日志记录
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# 创建文件处理器
file_handler = logging.FileHandler(log_file)
file_handler.setLevel(logging.INFO)

# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 将处理器添加到日志记录器
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 语言、模型和线程数配置
language = "Japanese"
model_name = "medium"
threads = 4  # 设置线程数

# 支持的音频文件扩展名
audio_extensions = (".mp3", ".wav", ".ogg", ".flac")

# 转录音频文件并保存结果
def transcribe_audio(audio_file, sub_folder_path):
    # 获取文件名(不包含扩展名)
    file_name = os.path.splitext(os.path.basename(audio_file))[0]
    # 生成每个子文件夹下的输出文件夹路径
    output_folder = os.path.join(sub_folder_path, "TranscriptionResults")
    # 检查输出文件夹是否存在,不存在则创建
    if not os.path.isdir(output_folder):
        os.makedirs(output_folder)
    # 生成输出文件的基本路径
    output_base_path = os.path.join(output_folder, file_name)

    # 记录开始时间
    start_time = time.time()
    logger.info(f"正在转录文件: {audio_file}")
    try:
        # 通过 subprocess 调用 Whisper 命令
        command = [
            "whisper", audio_file,
            "--language", language,
            "--model", model_name,
            "--threads", str(threads),
            "--output_dir", output_folder  # 指定输出目录
        ]

        # 执行命令
        subprocess.run(command, check=True)

        # 记录结束时间并计算转录时间
        end_time = time.time()
        elapsed_time = end_time - start_time
        logger.info(f"转录完成,所有结果已保存到: {output_folder}")
        logger.info(f"文件 {audio_file} 的转录花费了 {elapsed_time:.2f} 秒")
    except subprocess.CalledProcessError as e:
        logger.error(f"转录文件 {audio_file} 时出错: {e}")
    finally:
        pass

# 格式化总时间为 "天:小时:分钟:秒" 格式
def format_total_time(seconds):
    days = seconds // (24 * 3600)
    hours = (seconds % (24 * 3600)) // 3600
    minutes = (seconds % 3600) // 60
    seconds = seconds % 60
    return f"{int(days)}天 {int(hours)}小时 {int(minutes)}分钟 {int(seconds)}秒"

# 推送消息到PushDeer
def push_to_pushdeer(message, api_key, push_deer_url, push_title, push_type):
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    try:
        encoded_message = urllib.parse.quote(message, safe='')
        request_body = {
            "pushkey": api_key,
            "text": f"{push_title} {timestamp}",
            "desp": encoded_message,
            "type": push_type
        }
        response = requests.post(push_deer_url, data=request_body)

        if response.status_code == 200:
            logger.info("推送成功,时间为:{}".format(timestamp))
        else:
            logger.error(f"推送失败,状态码: {response.status_code}")
    except Exception as e:
        logger.error(f"推送失败:{e}")

# 主程序
if __name__ == "__main__":
    # 收集所有音频文件路径及其所在子文件夹路径
    audio_file_info = []
    for sub_folder in os.listdir(root_folder):
        sub_folder_path = os.path.join(root_folder, sub_folder)
        if os.path.isdir(sub_folder_path):
            for root_dir, _, files in os.walk(sub_folder_path):
                for file in files:
                    if file.lower().endswith(audio_extensions):
                        audio_file = os.path.join(root_dir, file)
                        audio_file_info.append((audio_file, sub_folder_path))

    # 记录总开始时间
    total_start_time = time.time()

    # 使用线程池并发处理音频转录
    for audio_file, sub_folder_path in audio_file_info:
        transcribe_audio(audio_file, sub_folder_path)

    # 记录总结束时间
    total_end_time = time.time()
    total_elapsed_time = total_end_time - total_start_time

    # 输出总转录时间
    logger.info(f"\n所有音频文件的转录全部完成,花费了 {format_total_time(total_elapsed_time)}")

    # 推送消息
    message = f"所有音频文件转录已完成,共花费了 {format_total_time(total_elapsed_time)}"
    api_key = "PDU1TVFy1tBulCz7Hq1ajeFqe6ccPwSbgw09x"
    push_deer_url = "http://43.153.151.226:8800/message/push"
    push_title = "转录动态推送"
    push_type = "markdown"

    push_to_pushdeer(message, api_key, push_deer_url, push_title, push_type)Code language: PHP (php)

评论 9

1 条主评论
写评论
  1. 你好,这是评论

    1. teddy 回复 @ch · 2026-06-24 09:08
      引用 @ch 你好,这是评论

      **石田**:ええ、創業 400 年以上の老舗で、長期にわたって寺院向けに仏前線香を販売してきました。江戸時代から一般向けの販売も始め、天然素材の香りを生活に取り入れる技術を継承しつつ、人々の暮らしに香りを届けてきました。
      → 石田:是的,创业 400 多年的老字号,长期为寺院供应佛前供香。从江户时代开始面向大众销售,传承将天然香料融入生活的技术,为人们传递香气。
      (仏前線香:ぶつぜんせんこう / 佛前供香;天然素材:てんねんそざい / 天然素材)

      **部長**:なるほど、だから我々が老舗の変革を手伝うというわけか。
      → 部长:原来如此,所以我们要协助老字号进行变革。

      **石田**:はい、歴史と伝統を誇る老舗は、新たな課題に立ち向かうことが求められています。特に少子高齢化が進むに従って、お客様も比較的年齢層が高いです。いかにして若い世代に商品の魅力を伝えるべきか、そこがポイントだと考えています。
      → 石田:是的,以历史和传统为荣的老字号,需要应对新挑战。尤其是随着少子老龄化加剧,客户群体年龄偏高。如何向年轻一代传递产品魅力是关键。
      (少子高齢化:しょうしこうれいか / 少子老龄化;年齡層:ねんれいそう / 年龄层)

      **社員 A**:そんな老舗なら、我が社に任せてくれるとは限らないですよね。同じようなことを考える競争相手も多そうですが。
      → 员工 A:这样的老字号,未必会把项目交给我们公司吧。应该有很多竞争对手也在打同样的主意。
      (任せて:まかせて / 委托;競争相手:きょうそうあいて / 竞争对手)

    2. teddy 回复 @ch · 2026-06-24 09:04
      引用 @ch 你好,这是评论

      是的 这是评论的样式修改

      1. teddy 回复 @teddy · 2026-06-24 09:08
        引用 @teddy 是的 这是评论的样式修改

        **中村**:あれ?由加ちゃんがいないですね。ここで待っているってさっき言っていたのに。
        → 中村:咦?由加酱不在呢。刚才还说在这里等的。
        (待っている:まっている / 等待;さっき:刚才)

        **佐藤**:あぁ、そういえば図書館に本を返してから来るって言っていました。
        → 佐藤:啊,对了,她说去图书馆还书后就来。
        (図書館:としょかん / 图书馆;返して:かえして / 归还)

    3. 如来佛主 回复 @ch · 2026-06-24 09:00
      引用 @ch 你好,这是评论

      你好,也是刚评论吗

      1. 引用 @如来佛主 你好,也是刚评论吗

        **由加**:読書会の課題図書だったから、借りたんだけど、花粉症のせいで、ほとんど読まずに、返却期限が来ちゃいました。
        → 由加:因为是读书会的指定书目,所以借了,但因为花粉症,几乎没读就到了归还期限。
        (読書会:どくしょかい / 读书会;返却期限:へんきゃくきげん / 归还期限)

        **佐藤**:僕も小学生の頃、その本を読んだことがあります。でも、内容が難しくて、ジョバンニが夢の中で、銀河鉄道に乗ったことだけは覚えているんですよ。
        → 佐藤:我小学的时候也读过这本书。但内容太难,只记得主人公乔凡尼在梦中乘坐银河铁道的情节。
        (小学生:しょうがくせい / 小学生;覚えて:おぼえて / 记得)

        1. teddy 回复 @teddy · 2026-06-24 09:09
          引用 @teddy 是的,这是平轮毂测试

          Prince George, Princess Charlotte and Prince Louis all attend Lambrook School, located in Berkshire. While the institution has not made a public announcement about a closure, many Berkshire schools nearby are closing at midday to stop the children, who are vulnerable to extreme heat, from being cooped up in the classroom. Even if the school remains open, outdoor play is almost certain to be capped, and it is likely that extra hydration provisions will be in place.

        2. teddy 回复 @teddy · 2026-06-24 09:07
          引用 @teddy 是的,这是平轮毂测试

          **由加**:本当にごめんなさい。図書館に本を返そうって思ったんだけど、さらに一ヶ月延長できるって聞いたから、手続きをしていました。そしたら、ちょっと時間がかかっちゃって。
          → 由加:真的非常抱歉。本来打算还书,但听说还能续借一个月,就办理了手续,结果耽误了时间。
          (延長:えんちょう / 延长;手続き:てつづき / 手续)

          **中村**:え?そんなにいい本なんですか。何という本?
          → 中村:欸?那本书有那么好吗?叫什么名字?

          **由加**:『銀河鉄道の夜』という本です。知っていますか?
          → 由加:是《银河铁道之夜》。你知道吗?
          (銀河鉄道の夜:ぎんがてつどうのよる / 宫泽贤治的童话作品)

写评论