【案例】【Mindspore】【离线权重转换系列0】MindSpore的离线权重转换接口说明及转换过程

一. 权重相关接口说明

权重转换主要涉及6个接口ckpt_to_safetensors、safetensors_to_ckpt、merge_pipeline_strategys 、transform_checkpoint、unified_safetensors和load_distributed_checkpoin

接口 使用链接 功能说明
ckpt_to_safetensors mindspore.ckpt_to_safetensors | MindSpore 2.4.0 文档 | 昇思MindSpore社区 权重格式从ckpt转到safetensors的转换 分布式权重和完整都可以
safetensors_to_ckpt mindspore.safetensors_to_ckpt | MindSpore 2.4.0 文档 | 昇思MindSpore社区 权重格式从safetensors到ckpt的转换 分布式权重和完整都可以
transform_checkpoint https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore/mindspore.transform_checkpoints.html?highlight=transform_checkpoints#mindspore.transform_checkpoints 由源切分策略转换到目标切分策略, 输入是ckpt输出只能是ckpt 输入是safetensors,输出可以ckpt或safetensors 入参必须是带rank的,完整权重放到rank0下 建议所有rank大小小于100G
unified_safetensors mindspore.unified_safetensors | MindSpore 2.4.0 文档 | 昇思MindSpore社区 将分布式safetensors文件合并为一份完整分片的safetensors文件。
load_distributed_checkpoint mindspore.load_distributed_checkpoint | MindSpore 2.4.0 文档 | 昇思MindSpore社区 将完整safetensors权重转换为分布式或完整的ckpt或safetensors权重 输入:格式safetensors 输出:2.4.0版本输出格式只能是safetensors,2.4.0之后可以是ckpt或safetensors,默认’safetensors’
merge_pipeline_strategys mindspore.merge_pipeline_strategys | MindSpore 2.4.0 文档 | 昇思MindSpore社区 策略文件合并

接口使用:

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

src_strategy_dirs:源策略文件,目录下面放了所有的策略文件,不需要按照rank存。
dst_strategy_file:合并后的策略文件,指定到策略文件名称,例如/xxx/xxx/merge.ckpt

  1. ckpt_to_safetensors :把ckpt转换为safetensors,分布式或完整ckpt都可以
import mindspore as ms  
ms.ckpt_to_safetensors(  
file_path="源ckpt文件的目录或文件",  
save_path="转换为safetensors文件的目录",  
processes_num=进程数) 

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

  1. safetensors_to_ckpt :把safetensors转换为ckpt,分布式或完整safetensors都可以
import mindspore as ms  
ms.safetensors_to_ckpt(  
file_path="safetensors权重文件或目录 ",  
save_path="转换为ckpt文件的目录",  
processes_num=进程数)  

file_path:源权重,**包含safetensors文件的目录路径或单个 safetensors **文件 (.safetensors) 的路径。备注:指定目录时必须按照rank存储
save_path:转换为ckpt文件的目录
processes_num:整数,可取4,8,16,32等,根据自己机器内存、cpu使用情况决定

  1. transform_checkpoint : 由源切分策略转换到目标切分策略
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:源权重的路径,分布式权重指定到rank的上一层路径,完整权重指定到文件名
dst_checkpoints_dir:目标权重的路径
ckpt_prefix:目标权重文件名的前缀
src_strategy_file:源权重合并后的策略文件,对于完整权重指定None
dst_strategy_file:目标权重合并后的策略文件,对于完整权重指定None
process_num:线程格数,根据自己机器cpu、内存使用情况绝对
output_format:“ckpt” 或 “safetensors”

  1. **unified_safetensors :**将分布式safetensors文件合并为一份完整分片的safetensors文件
import mindspore as ms  
ms.unified_safetensors(  
src_dir="safetensors格式的文件目录",  
src_strategy_file="源权重的切分策略(需合并)",  
dst_dir="生成文件的目录")  

src_dir: safetensors分布式权重的目录,指定到rank的上一层路径
src_strategy_file:源权重的切分策略(需合并)**** ,即merge_pipeline_strategys的输出结果
dst_dir:生成文件的目录

  1. load_distributed_checkpoint :将完整safetensors权重转换为分布式或完整的ckpt或safetensors权重
import mindspore as ms  
ms.load_distributed_checkpoint(  
network=None, #可以不是None,直接传入Net  
predict_strategy="目标权重的策略文件(合并后)", #完整权重指定None  
format='safetensors', #取值safetensors  
output_format='safetensors', #默认是'safetensors',取值ckpt或safetensors,2.4.0之后可以使用ckpt  
unified_safetensors_dir="离线合并后的目录(unified_safetensors的结果)",  
dst_safetensors_dir="生成目标权重目录" )  

二. 权重转换原则

原则一:权重是完整权重的,策略文件指定None
原则二: 策略文件和权重格式没有关系,同样策略,ckpt和safetensors可以共用策略文件。
原则三:分布式权重传rank上一层路径,完整权重传文件路径
原则四:对于权重所有rank加起来比较大的,建议都先转safetensors

三. 离线权重转换过程


以源A集群迁移到目标B集群为例:
第一步:获取所需要的相关文件,共需要以下三类文件

  1. 源集群A的切分策略信息:netA.strategy
  2. 源集群A的权重,每个rank的ckpt文件:rank_3/netA_10_6.ckpt

备注:每个进程生成一个目录,每个目录下有不同阶段的多个ckpt文件,上面的文件命名表示:这是第3个rank,在第10个epoch、第6个step训练结束时生成的ckpt文件

  1. 目标集群B的切分策略信息:netB.strategy

第二步:合并所有rank下的策略信息为一个完整的策略文件

  1. 默认情况,每张卡都会生成一个策略文件,但这个策略文件只表示这个pipeline下的切分策略,如果想得到集群完整的切分策略,需要把这些策略文件合并一下(源、目标都要合并)。使用ms.merge_pipeline_stratrge方法把他们合并成一个完整的策略

第三步:权重转换
有了第一步的三类文件,并进行了第二步的策略文件合并后,就可以进行权重转换了。
使用ms.transform_checkpoint方法,输入权重文件(目录)和集群A、集群B的策略文件,就可以输出集群B的权重文件了。
或者使用unified_safetensors ms.load_distributed_checkpoint进行权重转换


分布式ckp1转分布式ckp2:推荐红色流 ,权重不大可以使用蓝色流

相关案例:

场景 相关案例链接
场景一:safetensors转换为ckpt权重 https://www.hiascend.com/forum/thread-02111170995148192141-1-1.html
场景二:ckpt转换为safetensors权重 https://www.hiascend.com/forum/thread-02111170995148192141-1-1.html
场景三:ckpt分布式权重A转换为其他分布式权重B https://www.hiascend.com/forum/thread-0215170999041958157-1-1.html
场景四:完整ckpt权重转换为分布式权重 https://www.hiascend.com/forum/thread-02111171008716808146-1-1.html
场景五:分布式权重转换为完整ckpt权重 https://www.hiascend.com/forum/thread-02111171008716808146-1-1.html