Whisper 是 OpenAI 开发的一个自动语音识别(ASR)系统,它提供了不同大小的预训练模型,模型越大,通常在转录任务中的准确性就越高,但同时也需要更多的计算资源和更长的推理时间。
模型大小与精度
Whisper 一共有 5 种不同大小的模型,按照参数量从小到大依次为 tiny、base、small、medium 和 large,其中 large 又分为 large-v1 和 large-v2,large-v2 是目前最新且表现最优的版本。精度上,tiny 模型的准确性最低,而 large-v2 模型的准确性最高。以下是对各个模型的简要介绍:
| 模型名称 | 参数量 | 英文转录速度 | 多语言转录速度 | 特点 |
tiny | 39M | ~32x | ~16x | 速度极快,但精度较低,适用于对速度要求极高且对转录精度要求不高的场景。 |
base | 74M | ~16x | ~8x | 速度较快,精度一般,能满足一些基本的转录需求。 |
small | 244M | ~6x | ~3x | 速度适中,精度较好,在大多数情况下能提供较为准确的转录结果。 |
medium | 769M | ~2x | ~1.5x | 速度相对较慢,但精度较高,能处理一些复杂的语音内容。 |
large-v1 | 1550M | 1x | 1x | 精度很高,但速度最慢,对计算资源要求高。 |
large-v2 | 1550M | 1x | 1x | 在 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)
评论