【案例】【Mindspore】【离线权重转换系列二】MindSpore分布式ckpt权重A转换为其他策略的分布式权重B

使用场景:分布式策略改变后,训练所使用的卡数和分片策略都已改变,需要把源分布式权重转换为目标策略的分布式权重

方法一:推荐转换流程

cke_3484.png

step1:源权重A准备

源权重存储要求:按照权重路径 /rank_x/checkpoint_x.ckpt存储,且每个rank_x下面只能有一个权重文件。 训练yaml配置save_checkpoint_steps时,训练会按照配置的值为间隔,进行权重保存,因此路径下会有多个权重
(可选)把需要的ckpt 权重A挪到单独的目录中,**保证每个rank_x下面只有一个ckpt文件

for i in {0..4095}; do mkdir -p /fs_ssd5_dpc_llm/rank_${i}; mv /path/to/old_ckpt/rank_${i}/xxxx_rank_${i}_xxx.ckpt  /path/to/new_ckpt/rank_${i}; done

step2:分布式策略文件合并

需要把分布式权重A、B的策略文件分别合并

import mindspore as ms  
ms.merge_pipeline_strategys(  
src_strategy_dirs="源策略文件所在的目录",  
dst_strategy_file="合并后的策略文件名")  

src_strategy_dirs:A或B的源策略文件,目录下面放了所有的策略文件,不需要按照rank存。
dst_strategy_file:合并后的策略文件,指定到策略文件名称
需要根据https://gitee.com/mindspore/mindspore/pulls/76069/files添加改动,否则合并效率很低
样例脚本:

import mindspore as ms  
ms.merge_pipeline_strategys(  
src_strategy_dirs="/xxx/ckpt_convert/142strategy/",  
dst_strategy_file="/xxx/ckpt_convert/142merge.ckpt")  

输入:


输出:

step3:权重ckpt格式转换为safetensors

把分布式的ckpt权重转换成分布式的safetensors权重

import mindspore as ms  
ms.ckpt_to_safetensors(  
file_path="ckpt文件的目录",  
save_path="转换为safetensors文件的目录",  
processes_num="进程数")  

file_path:原始权重。
分布式权重:每个rank下面一个ckpt,指定到rank的上一层路径。
完整权重:指定到权重文件。
save_path:转换为safetensors文件的目录
processes_num:整数,可取8,16,32等,根据自己机器内存、cpu使用情况决定
样例脚本:

import mindspore as ms  
ms.ckpt_to_safetensors(  
file_path="/xxx/ckpt_convert/weight_o/142distributed_ckpt",  
save_path="/xxx/ckpt_convert/weight_o/142distributed_sf",  
processes_num=8)  

输入:


输出:

step4:分布式safetensors权重合并为完整safetensors分片权重

import mindspore as ms  
ms.unified_safetensors(  
src_dir="safetensors格式的文件目录",  
src_strategy_file="权重A的切分策略(需合并)",  
dst_dir="生成文件的目录")  

src_dir: safetensors分布式权重的目录
src_strategy_file:权重A的切分策略(需合并)
dst_dir:生成文件的目录
样例脚本:

import mindspore as ms  
ms.unified_safetensors(  
src_dir="/xxx/ckpt_convert/weight_o/142distributed_sf",  
src_strategy_file="/xxx/ckpt_convert/142merge.ckpt",  
dst_dir="/xxx/ckpt_convert/weight_o/142merge_sf")  

输入:合并的策略文件


输入:分布式的safetensors

输出:

step5:切分safetensors权重

通过load_distributed_checkpoint可以将完整分片的safetensors权重转换为
1)完整ckpt 2)分布式ckpt 3)完整safetensors 4)分布式safetensors
备注:输入:格式safetensors 输出:2.4.0版本输出格式只能是safetensors,2.4.0之后可以是ckpt或safetensors,默认’safetensors’

import mindspore as ms  

ms.load_distributed_checkpoint(  
network=None, #可以不是None,直接传入Net  
predict_strategy="权重B的策略文件(合并后)", #完整权重指定None  
format='safetensors', #取值safetensors  
output_format='safetensors', #默认是'safetensors',取值ckpt或safetensors,2.4.0之后可以使用  
unified_safetensors_dir="离线合并后的目录(上一步产生的)",  
dst_safetensors_dir="生成的权重B目录" )  

样例: 8卡 dp1mp4pp2转16卡 dp1mp4pp4
脚本:

import mindspore as ms  

ms.load_distributed_checkpoint(  
network=None,  
checkpoint_filenames=None,  
predict_strategy="/xxx/ckpt_convert/144merge.ckpt",  
format='safetensors',  
output_format='safetensors',  
unified_safetensors_dir="/xxx/ckpt_convert/weight_o/142merge_sf",  
dst_safetensors_dir="/xxx/ckpt_convert/weight_o/144distributed_sf" )  

输入:


输出分布式权重:

step6: (2.4.0必须) safetensors转ckpt

import mindspore as ms  

ms.safetensors_to_ckpt(  
file_path="safetensors权重文件或目录 ",  
save_path="转换为ckpt文件的目录",  
processes_num="进程数")  

样例:

import mindspore as ms  

ms.safetensors_to_ckpt(  
file_path="/xxx/ckpt_convert/weight_o/sf_all",  
save_path="/xxx/ckpt_convert/weight_o/sf_to_ckpt_all",  
processes_num= 8)  

输入:


输出完整权重截图:

方法二:小权重转换使用transform_checkpoints

import mindspore as ms  

ms.transform_checkpoints (src_checkpoints_dir, dst_checkpoints_dir, ckpt_prefix, src_strategy_file=None, dst_strategy_file=None, process_num=1, output_format='ckpt')  
print("Transform ckpt DONE", flush=True)  
  • src_checkpoints_dir:权重A的路径,分布式权重指定到rank的上一层路径,完整权重指定到文件名
  • dst_checkpoints_dir:生成权重B的路径
  • ckpt_prefix:生成权重B文件名的前缀
  • src_strategy_file:权重A合并后的策略文件,对于完整权重指定None
  • dst_strategy_file:权重B合并后的策略文件,对于完整权重指定None
  • process_num:线程格数,根据自己机器cpu、内存使用情况绝对
  • output_format:“ckpt” 或 “safetensors”