附录

DataFlow框架介绍

DataFlow框架结构

图1 DataFlow框架结构

DataFlow结构可以分为3层,各层介绍如下。

  • DataFlow API:负责异构计算流表达,App开发人员使用DataFlow API表达业务的数据流,生成基于Graph IR的计算图。数据流表达详细描述请参见“数据流表达”。
  • 异构并行编译器:负责异构计算图编译,将计算图基于异构计算单元的组成关系和连接拓扑进行图切分、图优化和图部署,生成各个异构计算单元的执行Bin。
  • 异构Runtime:根据异构计算图编译输出的结果,将执行Bin调度到对应的异构执行单元上执行。异构Runtime详细描述请参见“异构Runtime”。

数据流表达

数据流图表达的规则和约束如下。

  • FlowGraph是DAG(Directed Acyclic Graph)图,数据流有向且不允许有成环表达。

  • 不支持无输入或无输出的FlowGraph。

  • 节点间流转的数据可能存在多节点共享,要保证不可变,因此不允许计算节点修改输入数据,必要时需要做拷贝处理。

  • 数据流支持1对多,表示复制相同数据后分发给多个Node;但同一个节点的多个输出发给同一个输入。

  • 支持表达调用GraphProcessPoint执行,实现控制流表达如循环迭代,分支控制逻辑如下。

异构Runtime

异构Runtime针对CPU、NPU异构节点提供不同的执行器,包括如下。

  • CPU图执行器:部署在CPU节点,用于执行计算图。
  • NPU图执行器:部署于NPU,用于执行计算图。
  • UDF执行器:自定义Func执行引擎,可灵活部署于CPU节点或使用NPU上的AICPU。

各执行器以独立进程方式部署,每个执行进程间采用如下数据通信方式交互数据:在同一节点内采用共享内存、共享队列;跨节点使用RDMA/UB高性能通信。

执行器间数据流的生产、消费关系/1对多分发关系/跨节点数据通信统一由FlowGW(数据流网关)代理并转发。

Mbuf多内存

功能介绍

Mbuf是一种共享内存,包含了MbufHead和MbufData两部分数据,如表1所示。

表1 Mbuf介绍

数据类型 描述
MbufHead 即数据头,包含了以下几类数据:基础的数据内容:比如DataType/DataSize/Shape等信息。数据传递涉及的关键信息:retCode/routeLabel等框架相关信息。其他用户可配置字段:starttime/endtime/userdata等。
MbufData 一段Mbuf上的内存,存储了实际上有效的数据内容。

在DataFlow的内存分配场景中,Mbuf是驱动对于内存管理的统一机制,所有的FlowMsg都会在Mbuf池中进行生成并使用。每个FlowMsg都会申请一段Mbuf内存:

sizeMbuf  =
       sizeof(MbufData) // FlowMsg实际包含的内存大小
     + sizeof(MbufHead) // MbufHead大小,实际为1024B

说明

FlowMsg是FlowGraph上节点间传递信息的载体,用于处理FlowFunc输入输出的相关操作。FlowMsg使用共享内存Mbuf来保存信息。

背景信息

用户存在大量UDF进程,且每个UDF进程都可能申请大量小内存的场景下,建议使用Mbuf多内存池。如下举例说明。

假设Mbuf内存池总大小是10GB,不使用Mbuf多内存池时,由于内存碎片的存在,无法申请连续的大块内存。详细信息如下。

  1. 在time1的时间点,申请了多个大块内存(3GB)和多个小块内存(2MB)。
  2. 在time2的时间点上,大内存不再使用,释放给内存池变为空闲状态。此时,从内存池整体状况来看,整体内存使用情况是:3GB(空闲)+2MB(已申请)+3GB(空闲)+2MB(已申请)+3GB(空闲)+2MB(已申请),可用内存为9GB+。
  3. 在time3的时间点上,虽然可用内存为9GB+,但是由于内存碎片(2MB内存块)的存在,所以申请5GB的连续内存失败。

使用示例

针对上述场景,需要额外新增内存池配置,用以处理内存碎片问题。主要方法是,将Mbuf设置为可配置多内存池系统,小内存放入专用小内存池中。

Mbuf多内存池示例图如下。

  1. 在time1的时间点,申请了多个大块内存(3GB)和多个小块内存(2MB)。

  2. 在time2的时间点上,大内存不再使用,释放给内存池变为空闲状态。此时,从内存池整体状况来看,整体内存使用情况是:3GB(空闲)+3GB(空闲)+3GB(空闲)+2MB(已申请)+2MB(已申请),内存池1中可用内存为9GB+,内存池2中可用内存为1G+。

  3. 在time3的时间点上,内存池1中可用连续内存为9GB+,申请5GB的内存成功。

该方案是通过配置“ge.flowGraphMemMaxSize”实现的,配置示例如表2中的示例二。

表2 配置示例

示例名 示例描述 示例代码
示例一 申请一个内存池,大小为10GB,申请内存大小不限制。 {"ge.flowGraphMemMaxSize", "10737418240"}
示例二 申请两个内存池。
- 内存池1大小为10GB,申请内存大小不限制。
- 内存池2大小为2GB,最大可以申请2MB。
申请内存<=2MB时会优先在内存池2中申请,申请内存>2MB时只能在内存池1中申请。
{"ge.flowGraphMemMaxSize", "10737418240,2147483648:2097152"}
示例三 申请三个内存池。
- 内存池1大小为10GB,申请内存大小不限制。
- 内存池2大小为2GB,最大可以申请20MB。
- 内存池3大小为1GB,最大可以申请2MB。
申请内存时会根据申请内存大小优先匹配对应的内存池,比如申请内存<=2MB时会优先在内存池3中申请,2MB<申请内存<=20MB的优先在内存池2中申请,申请内存>20MB的只能在内存池3中申请。
{"ge.flowGraphMemMaxSize", "10737418240,2147483648:20971520,1073741824:2097152"}

说明


ge.flowGraphMemMaxSize具体含义如下。
FlowGraph场景下,网络可使用的内存配置,可根据网络大小指定。单位:Byte,可以支持多个内存池配置,最多支持128个内存池,配置格式为"内存池1大小:申请内存限制,内存池2大小:内存申请限制,...,内存池n大小:内存申请限制",如果不设置,默认单个内存池,大小10GB,申请内存大小不限制。
内存池大小取值范围为[1024, 274877906944],单位为Byte,所有内存池大小加起来不能超过256GB,实际使用时受硬件限制。
申请内存限制取值范围为0或者[1024,2147483648],单位为Byte,为可选配置,默认为0,表示不限制。

numa_config.json配置

numa_config.json全量字段含义如表1所示。

表1 字段说明

名称 类型 是否必选 描述
Cluster - - -
cluster_nodes Array of cluster_nodeCluster_node详细介绍请参见表2。 集群资源信息描述。
nodes_topology nodes_topologynodes_topology详细介绍请参见表5。 跨节点通信拓扑。如两台AISERVER间参数面通信拓扑。
node_def:集群内同种类型node的公共属性 - - -
node_type String 节点类型。示例如:Atlas A2 训练系列产品/Atlas A2 推理系列产品场景下:ATLAS900。
resource_type String UDF可部署的架构和CPU资源类型。取值为X86或者Aarch。
support_links String 节点内通信方式。如[HCCS,PCIE,ROCE]。
item_type String 节点内加速卡类型。示例:Atlas A2 训练系列产品/Atlas A2 推理系列产品场景:AscendxxxB1、AscendxxxB2、AscendxxxB3、AscendxxxB4。Atlas A3 训练系列产品/Atlas A3 推理系列产品场景:Ascend910_xx
inter_item_memory_access_mode String Server内不同device的地址互访方式。取值范围:NUMA或者UMA。
h2d_bw String HOST-DEVICE间带宽如PCIE:100Gb。
item_topology item_topologyitem_topology详细信息请参见表6。 节点内不同加速卡间互联信息。Atlas A2 训练系列产品/Atlas A2 推理系列产品云场景下,按照1/2/4/8卡发放加速卡,故若只有1张卡则不涉及多卡拓扑。
item_def:node内同种类型的加速卡的公共属性 - - -
item_type String 节点内加速卡类型。示例:Atlas A2 训练系列产品/Atlas A2 推理系列产品场景:AscendxxxB1、AscendxxxB2、AscendxxxB3、AscendxxxB4。
memory String 整芯片总内存。 Atlas A2 训练系列产品/Atlas A2 推理系列产品场景下,请配置为[DDR:64GB]。Atlas A3 训练系列产品/Atlas A3 推理系列产品场景下,请配置为[DDR:31GB]。
aic_type String 加速卡计算核类型和核数。如[DAVINCI_V100:32]。
resource_type String UDF可部署的Ascend资源类型。请配置为Ascend。

表2 cluster_node说明

名称 类型 是否必选 描述
node_id Integer 集群内节点编号,一般0作为主节点。
node_type String 节点类型。示例:Atlas A2 训练系列产品/Atlas A2 推理系列产品场景下:ATLAS900。
ipaddr String 节点控制面通信的IP。如训练服务器为HOST IP。
port Integer 节点控制面通信的端口。
data_panel NetworkInfo 数据面通信信息。
memory Integer 应用HOST上可用内存。
is_local BOOL 多个Node组成集群时,此文件此节点是否是本机。
auth_lib_path String 用来标识DataFlow需要dlopen的库文件:auth_lib_path字段由云助端CaaS写入,主从调度进程负责读取并加载so和调用相关接口。
deploy_res_path String 模型文件存放路径。root用户默认路径:/root/runtime/deploy_res。非root用户默认路径:${home}/runtime/deploy_res。
item_list Array of item_infoitem_info详细信息请参见表4。 云资源管理编排的执行该JOB的加速卡。

表3 NetworkInfo说明

名称 类型 是否必选 描述
avail_ports Array of String 在每个节点上该应用实例可用的数据面通信端口号范围。承载的业务如下。FlowGW异步点到点通信:HOST FlowGW和Device FlowGW通信走PCIE,不会占用HOST OS端口号;Device间FlowGW通信需要为通信分配唯一的端口号。集合通信:send/recv入图点到点、ranktbl集合通信。多个Device间FlowGW通信支持协议RDMA。多个Device间端口号默认分配范围为16666~32767,用户可自定义配置。

表4 Item_info说明

名称 类型 是否必选 描述
item_id Integer Node内加速卡逻辑ID。
device_id Integer Node内加速卡物理ID。
ipaddr String 通信使用的IP地址或网段信息。

表5 nodes_topology说明

名称 类型 是否必选 描述
type String 通信库根据拓扑类型来确定选择的通信算法。如star。
protocol String Node间通信协议类型,默认值为RDMA。单Server不需要配置该字段。示例:RDMA:200Gb。
topos Array of planeplane详细信息请参考表8 Node间加速卡互联平面信息。

表6 item_topology说明

名称 类型 是否必选 描述
links_mode String 节点内不同加速卡间通信方式和带宽。如HCCS:128Gb。
links Array of item_pairitem_pair详细信息请参见表7。 节点内不同加速卡间互联拓扑。如[0, 1]。

表7 item_pair说明

名称 类型 是否必选 描述
item_id Integer 加速卡ID。
pair_item_id Integer 成对的加速卡ID。

表8 plane说明

名称 类型 是否必选 描述
plane_id Integer server间通信平面是第几个plane(云提供)。
devices Array of int list 属于该平面的加速卡列表。

Atlas A2 训练系列产品/Atlas A2 推理系列产品场景下的numa_config.json示例

numa_config.json示例如下,全量字段含义如表1所示。

{
  "cluster":[
    {
      "cluster_nodes": [
        {
          "node_id":0,
          "node_type": "ATLAS900",
          "ipaddr": "xx.xx.xx.xx",
          "port":2509,
          "memory":25165824,
          "is_local":true,
          "auth_lib_path": "/opt/huawei/config/ascend_config/dataflow/lib/libcaas_dataflow_auth.so",
          "deploy_res_path": "/home/",
          "item_list" : [
           {
             "item_id":0,
             "device_id":0,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":1,
             "device_id":1,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":2,
             "device_id":2,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":3,
             "device_id":3,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":4,
             "device_id":4,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":5,
             "device_id":5,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":6,
             "device_id":6,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":7,
             "device_id":7,
             "ipaddr":"xx.xx.xx.xx"
           }
          ]
        }
      ],
      "nodes_topology":
      {
        "protocol": "RDMA:200Gb",
        "type" : "star",
        "topos" : [
          {
            "plane_id" : 0,
            "devices" : [0, 1, 2, 3, 4, 5, 6, 7]
          },
        ]
      }
    }
  ],
  "node_def": [
    {
      "node_type": "ATLAS900" ,
      "resource_type": "Aarch",
      "support_links": "[HCCS,PCIE,ROCE]" ,
      "item_type": "AscendxxxB1",
      "inter_item_memory_access_mode": "[NUMA]",
      "h2d_bw": "PCIE:100Gb",
      "item_topology": [
        {
          "links_mode": "HCCS",
          "links": [ [0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],
                   [1,2],[1,3],[1,4],[1,5],[1,6],[1,7],
                   [2,3],[2,4],[2,5],[2,6],[2,7],
                   [3,4],[3,5],[3,6],[3,7],
                   [4,5],[4,6],[4,7],
                   [5,6],[5,7],
                   [6,7]]
        }
      ]
    }
  ],
  "item_def": [
    {
      "item_type": "AscendxxxB1",
      "resource_type": "Ascend",
      "memory": "[DDR:64GB]",
      "aic_type": "[DAVINCI_V100:32]"
    }
  ]
}

Atlas A3 训练系列产品/Atlas A3 推理系列产品场景下的numa_config.json示例

numa_config.json示例如下,全量字段含义如表1所示。

{
  "cluster":[
    {
      "cluster_nodes": [
        {
          "node_id":0,
          "node_type": "ATLAS800",
          "ipaddr": "xx.xx.xx.xx",
          "port":2509,
          "memory":25165824,
          "is_local":true,
          "auth_lib_path": "/opt/huawei/config/ascend_config/dataflow/lib/libcaas_dataflow_auth.so",
          "deploy_res_path": "/home/",
          "item_list" : [
           {
             "item_id":0,
             "device_id":0,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":1,
             "device_id":1,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":2,
             "device_id":2,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":3,
             "device_id":3,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":4,
             "device_id":4,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":5,
             "device_id":5,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":6,
             "device_id":6,
             "ipaddr":"xx.xx.xx.xx"
           },
           {
             "item_id":7,
             "device_id":7,
             "ipaddr":"xx.xx.xx.xx"
           }
          ]
        }
      ],
      "nodes_topology":
      {
        "protocol": "RDMA:200Gb",
        "type" : "star",
        "topos" : [
          {
            "plane_id" : 0,
            "devices" : [0, 1, 2, 3, 4, 5, 6, 7]
          },
        ]
      }
    }
  ],
  "node_def": [
    {
      "node_type": "ATLAS900" ,
      "resource_type": "Aarch",
      "support_links": "[HCCS,PCIE,ROCE]" ,
      "item_type": "AscendxxxB1",
      "inter_item_memory_access_mode": "[NUMA]",
      "h2d_bw": "PCIE:100Gb",
      "item_topology": [
        {
          "links_mode": "HCCS",
          "links": [ [0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],
                   [1,2],[1,3],[1,4],[1,5],[1,6],[1,7],
                   [2,3],[2,4],[2,5],[2,6],[2,7],
                   [3,4],[3,5],[3,6],[3,7],
                   [4,5],[4,6],[4,7],
                   [5,6],[5,7],
                   [6,7]]
        }
      ]
    }
  ],
  "item_def": [
    {
      "item_type": "Ascend910_xx",
      "resource_type": "Ascend",
      "memory": "[DDR:31GB]",
      "aic_type": "[DAVINCI_V100:32]"
    }
  ]
}

UDF Python工程创建工具

该工具的作用是创建一个UDF Python工程模板,包括对应的文件夹和文件,用户可以基于该模板进行功能的开发,减少了手工创建的工作量。

该工具存放路径:${install_path}/cann/python/site-packages/dataflow/tools/create_func_ws.py,其中${install_path}为CANN软件的安装目录,默认是"/usr/local/Ascend"。

使用方法如下。

  1. 设置环境变量。

    安装CANN软件后,使用CANN运行用户进行编译、运行时,需要以CANN运行用户登录环境,执行source ${INSTALL_DIR}/set_env.sh命令设置环境变量。${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。以root用户安装为例,安装后文件默认存储路径为:/usr/local/Ascend/cann。

  2. 创建UDF Python工程。

    如下以创建工作目录为“test_sub”的工程为例,说明如何创建。

    在任意路径下执行如下命令。

    python3.11 -m dataflow.tools.create_func_ws -f sub:i0:i1:o0 -w ./test_sub -c Sub
    

    在当前目录下,生成如下“test_sub”文件夹,目录结构如下。

    ├── CMakeLists.txt  // CMakeLists编译配置文件,一般不需要用户改动。如果打包需要特殊处理可以修改,比如打包时增加配置文件发布。
    ├── func_sub.json // UDF配置文件,用于指定UDF的输入,输出等,一般不需要用户改动,如果生成工作workspace目录和实际运行时不一致,需要修改文件中workspace参数为实际运行时路径。
    ├── src_cpp
    │   └── func_sub.cpp  // 完成UDF注册,以及UDF的C++调用Python的逻辑,不需要用户改动。
    └── src_python
        └── func_sub.py  // 用户的实现函数,需要用户自行编写,当前目录下可以增加多个Python文件,打包时会一并打包到运行环境。
    

    命令中各参数含义如下。

    • -m:必选参数,Python命令行通用参数,作为脚本运行库模块,该工具中固定为dataflow.tools.create_func_ws。
    • -f:必选参数,输入函数信息、输入和输出索引,格式为“函数名:ix:ix🐂ox”,i开头表示输入,后面跟输入索引,o开头表示输出,后面跟输出索引,多个函数的话中间以半角逗号分隔。例如,sub:i0:i1:o0,该示例中,函数名为sub(会直接作为Python函数名,建议采用小写加下划线风格,同时生成的cpp代码会按照大驼峰拼接“Proc”作为cpp函数),两个输入:i0和i1,一个输出o0。
    • -w:可选参数,工作目录。例如,./test_sub,该示例中,指定工作目录是当前目录下的“test_sub”,默认值为当前目录“./”,注意:生成的文件会直接覆盖工作空间中重名的文件。
    • -c:可选参数,函数类名。例如,Sub(会直接作为Python和c++类名,建议使用大驼峰风格),为空时会使用-f参数中的函数名拼接生成。

该工具的更多使用参数请通过“-h”进行查看。