modelscope-funasr1.0 微调热词模型,单机多卡出现上述问题,会是啥原因?单机单卡可以跑通环境安装:
python==3.8.5
torch==2.0.1
funasr==1.0.19
使用模型:
[[https://www.modelscope.cn/models/damo/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch/summary]]
参考示例:
[[https://github.com/alibaba-damo-academy/FunASR/blob/5e7eb6f160c48861cbcd39825a0cb98f98538772/examples/industrial_data_pretraining/seaco_paraformer/finetune.sh]]
代码修改将GPU卡设置成2卡 (单卡可以跑通)
export CUDA_VISIBLE_DEVICES="0,1"
++dataset_conf.batch_type="example"
++dataset_conf.batch_size=10
错误信息:
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one等
根据您提供的信息,modelscope-funasr
在单机多卡环境下运行时出现了错误,而单机单卡环境可以正常运行。错误信息为:
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one
此问题通常与分布式训练的同步机制有关,尤其是在使用 PyTorch 的 torch.distributed
模块时。以下是对问题的详细分析和解决方案。
在单机多卡环境下,PyTorch 使用 torch.distributed
进行多 GPU 的分布式训练。如果分布式训练的初始化或同步配置不正确,可能会导致上述错误。
解决方法: - 确保正确初始化分布式训练环境。例如,在代码中添加以下内容:
import torch.distributed as dist
dist.init_process_group(backend="nccl", init_method="env://")
backend="nccl"
是推荐的后端,适用于 NVIDIA GPU。init_method="env://"
表示从环境变量中读取初始化参数(如 MASTER_ADDR
, MASTER_PORT
, WORLD_SIZE
, RANK
等)。
设置环境变量以支持多卡训练:
export MASTER_ADDR="localhost"
export MASTER_PORT="12345"
export WORLD_SIZE=2 # 总 GPU 数量
export RANK=0 # 当前进程的 GPU 编号
torchrun
启动脚本,可以直接通过命令行指定参数:
torchrun --nproc_per_node=2 finetune.sh
在多卡训练中,batch_size
的设置需要考虑每个 GPU 的负载。如果 batch_size
过大或过小,可能会导致梯度同步失败。
解决方法: - 调整 batch_size
参数,确保其适合多卡环境。例如:
dataset_conf.batch_size=5 # 将 batch_size 减半,适应多卡分配
batch_size
,可以通过梯度累积实现:
accumulation_steps = 2 # 梯度累积步数
optimizer.zero_grad()
for i, data in enumerate(dataloader):
outputs = model(data)
loss = outputs.loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
您设置了 export CUDA_VISIBLE_DEVICES="0,1"
,但未明确说明是否正确映射到分布式训练的 RANK
。如果 CUDA_VISIBLE_DEVICES
和 RANK
不匹配,可能会导致 GPU 之间的通信失败。
解决方法: - 确保 CUDA_VISIBLE_DEVICES
和 RANK
的映射关系正确。例如:
export CUDA_VISIBLE_DEVICES="0,1"
export RANK=0 # 对应 GPU 0
export RANK=1 # 对应 GPU 1
torchrun
,它会自动处理 CUDA_VISIBLE_DEVICES
和 RANK
的映射,无需手动设置。某些模型可能未完全支持多卡并行化,尤其是自定义模型或特定版本的 funasr
。如果模型的前向传播或反向传播未正确处理多卡同步,可能会导致错误。
解决方法: - 检查模型代码,确保所有张量操作都支持分布式训练。例如,使用 torch.nn.parallel.DistributedDataParallel
包装模型:
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[local_rank])
local_rank
是当前进程的 GPU 编号,可通过环境变量获取:
local_rank = int(os.environ["LOCAL_RANK"])
如果模型本身不支持分布式训练,可以尝试使用单卡训练,或将模型迁移到支持分布式训练的框架。
您提到的环境配置为: - Python==3.8.5 - PyTorch==2.0.1 - FunASR==1.0.19
这些版本可能存在兼容性问题,尤其是在多卡环境下。
解决方法: - 确保所有依赖版本兼容。建议参考官方文档或社区推荐的版本组合。 - 更新 funasr
到最新版本,修复可能存在的多卡训练问题:
pip install --upgrade funasr
检查分布式训练配置
torch.distributed
。torchrun
启动脚本。调整 Batch Size 和梯度累积
batch_size
。batch_size
,启用梯度累积。验证 CUDA_VISIBLE_DEVICES 和 RANK 映射
CUDA_VISIBLE_DEVICES
和 RANK
的映射关系正确。检查模型并行化支持
DistributedDataParallel
包装模型。更新依赖版本
funasr
和其他依赖库,确保版本兼容。上述问题的根本原因可能是分布式训练配置不当、Batch Size 设置不合理、CUDA_VISIBLE_DEVICES 映射错误或模型未完全支持多卡并行化。通过逐步排查和调整配置,可以解决该问题。如果问题仍然存在,建议参考官方文档或社区支持,进一步调试和优化。您可以复制页面截图提供更多信息,我可以进一步帮您分析问题原因。