# MindSpore的离线权重转换接口说明及转换过程

**1. 权重相关接口说明**

权重转换主要涉及6个接口ckpt\_to\_safetensors、safetensors\_to\_ckpt、merge\_pipeline\_strategys 、transform\_checkpoint、unified\_safetensors和load\_distributed\_checkpoin


<table><tbody><tr id="row155521410497"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p1655217417499">接口</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p755210414497">使用链接</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p1552134124911">功能说明</p>
</td>
</tr>
<tr id="row55527444918"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p25529411499">ckpt_to_safetensors</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p3552164194915">https://www.mindspore.cn/docs/zh-CN/r2.4.0/api_python/mindspore/mindspore.ckpt_to_safetensors.html?highlight=ckpt_to_safetensors#mindspore.ckpt_to_safetensors</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p155521544495">权重格式从ckpt转到safetensors的转换</p>
<p id="p95529414916">分布式权重和完整都可以</p>
</td>
</tr>
<tr id="row125524494915"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p1455244104916">safetensors_to_ckpt</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p19552104174919">https://www.mindspore.cn/docs/zh-CN/r2.4.0/api_python/mindspore/mindspore.safetensors_to_ckpt.html?highlight=safetensors_to_ckpt#mindspore.safetensors_to_ckpt</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p175525412496">权重格式从safetensors到ckpt的转换</p>
<p id="p4552942495">分布式权重和完整都可以</p>
</td>
</tr>
<tr id="row1555216444915"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p195521942492">transform_checkpoint</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p35528416495">https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore/mindspore.transform_checkpoints.html?highlight=transform_checkpoints#mindspore.transform_checkpoints</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p75521242497">由源切分策略转换到目标切分策略,</p>
<p id="p105527418491">输入是ckpt输出只能是ckpt</p>
<p id="p145531646493">输入是safetensors，输出可以ckpt或safetensors</p>
<p id="p455310419495">入参必须是带rank的，完整权重放到rank0下</p>
<p id="p555354124920">建议所有rank大小小于100G</p>
</td>
</tr>
<tr id="row18553144194915"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p1555320413497">unified_safetensors</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p2055318417494">https://www.mindspore.cn/docs/zh-CN/r2.4.0/api_python/mindspore/mindspore.unified_safetensors.html?highlight=unified_safetensors#mindspore.unified_safetensors</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p18553841497">将分布式safetensors文件合并为一份完整分片的safetensors文件。</p>
</td>
</tr>
<tr id="row955319424919"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p65530424910">load_distributed_checkpoint</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p175539444917">https://www.mindspore.cn/docs/zh-CN/r2.4.0/api_python/mindspore/mindspore.load_distributed_checkpoint.html?highlight=load_distributed_checkpoint#mindspore.load_distributed_checkpoint</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p105531418499">将完整safetensors权重转换为分布式或完整的ckpt或safetensors权重</p>
<p id="p555320410493">输入：格式safetensors</p>
<p id="p16553647499">输出：2.4.0版本输出格式只能是safetensors，2.4.0之后可以是ckpt或safetensors，默认'safetensors'</p>
</td>
</tr>
<tr id="row2055314174920"><td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p555311412495">merge_pipeline_strategys</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p95533434917">https://www.mindspore.cn/docs/zh-CN/r2.4.0/api_python/mindspore/mindspore.merge_pipeline_strategys.html?highlight=merge_pipeline_strategys#mindspore.merge_pipeline_strategys</p>
</td>
<td class="cellrowborder" valign="top" width="33.333333333333336%"><p id="p5553164154912">策略文件合并</p>
</td>
</tr>
</tbody>
</table>

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

    ![](figures/zh-cn_image_0000002309045705.png)

2.  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使用情况决定

    分布式权重存储样例：

    ![](figures/zh-cn_image_0000002274550568.png)

3.  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使用情况决定

4.  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"

5.  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：生成文件的目录

6.  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="生成目标权重目录" )
```

**2. 权重转换原则**

原则一：权重是完整权重的，策略文件指定None

原则二： 策略文件和权重格式没有关系，同样策略，ckpt和safetensors可以共用策略文件。

原则三：分布式权重传rank上一层路径，完整权重传文件路径

原则四：对于权重所有rank加起来比较大的，建议都先转safetensors

**3. 离线权重转换过程**

![](figures/zh-cn_image_0000002274456252.png)以源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进行权重转换

![](figures/zh-cn_image_0000002309129665.png)分布式ckp1转分布式ckp2：推荐红色流，权重不大可以使用蓝色流

相关案例：


<table><tbody><tr id="row18406175355719"><td class="cellrowborder" valign="top" width="50%"><p id="p1240611537577">场景</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1940611531571">相关案例链接</p>
</td>
</tr>
<tr id="row154061453195714"><td class="cellrowborder" valign="top" width="50%"><p id="p740611537572">场景一：safetensors转换为ckpt权重</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p54061553105717">https://www.hiascend.com/forum/thread-02111170995148192141-1-1.html</p>
</td>
</tr>
<tr id="row1540675395710"><td class="cellrowborder" valign="top" width="50%"><p id="p10406155319577">场景二：ckpt转换为safetensors权重</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1140619531578">https://www.hiascend.com/forum/thread-02111170995148192141-1-1.html</p>
</td>
</tr>
<tr id="row540695395710"><td class="cellrowborder" valign="top" width="50%"><p id="p17406195305715">场景三：ckpt分布式权重A转换为其他分布式权重B</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1740685318572">https://www.hiascend.com/forum/thread-0215170999041958157-1-1.html</p>
</td>
</tr>
<tr id="row1340615315573"><td class="cellrowborder" valign="top" width="50%"><p id="p54063535572">场景四：完整ckpt权重转换为分布式权重</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p19406653195719">https://www.hiascend.com/forum/thread-02111171008716808146-1-1.html</p>
</td>
</tr>
<tr id="row6406175385718"><td class="cellrowborder" valign="top" width="50%"><p id="p14061953135719">场景五：分布式权重转换为完整ckpt权重</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p13406753135717">https://www.hiascend.com/forum/thread-02111171008716808146-1-1.html</p>
</td>
</tr>
</tbody>
</table>

