异构并行计算框架的分层如下:
-
Dispatcher 算法整体调度: 采用Dispatcher进行算法的并行调度(例如LLM推理调度,HPC调度);
-
Worker的异构设计:拆分算法并部署到各异构设备的Worker对象,对上层调度者(Dispatcher)提供统一的接口,以达到算法流程的统一调度;
-
底层算子异构实现:该框架的底层算子实现由各异构设备具体实现,同时向上对Worker提供统一的接口,便于调度; 重点添加神经网络相关异构算子,即可实现异构框架的模型推理。
整体框架基于 Ray Serve API 进行开发,所有Workers和Dispatcher都注册为Ray的Actor。
heterogeneous_serve/ops.py— torch 矩阵算子注册表(matmul/add/sub/mul/transpose/inverse/det/chain_matmul),@register_op可扩展heterogeneous_serve/worker.py— 统一DeviceWorker:按启动时注入的 compute 配置,在绑定设备上执行矩阵算子和/或 Qwen3.5 模型分片计算heterogeneous_serve/dispatcher.py— HTTP ingress,并行扇出/汇聚、跨设备结果一致性校验heterogeneous_serve/config.py/app.py— 配置与应用组装(Ray Serve 模型组合)run.py— 启动入口;client.py— 示例客户端
- 服务创建初始化
- 异构设备初始化:每一类异构设备创建一个DeviceConfig实例,所有的DeviceConfig实例构成一个FrameworkConfig实例;
- Application创立:通过build_app函数,创建异构服务集群,该集群会通过DeviceConfig实例对所有Workers(一个worker对应一类计算设备)进行Ray.serve.Deployment注册; 并将注册后的handle传递给Dispatcher,并将Dispatcher注册为一个顶层的Deployment,Workers和Dispatcher均视为Ray的Actor;
- Dispatcher服务-运行算法,输出结果到客户:Dispatcher实现算法服务的具体调度,Dispatcher/Dispatcher_base类中每一个带有@fastapi_app装饰符均被注册为一个计算服务;
- 远程client服务请求:向创建好的异构集群服务器post计算服务(服务器设定好的)和输入参数,以运行计算任务;
# 现阶段采用torch进行算子的具体实现,在源码根目录下的requirements.txt包含所有依赖的pip库。
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # NPU 环境需另外安装 torch_npuheterogeneous_compute
├── heterogeneous_serve # 依托于ray server的核心代码
│ ├── config.py # 异构计算框架配置
│ ├── device.py # 异构设备配置
│ ├── dispatcher.py # dispatcher调度基础代码,创建后配置为ray actor
│ ├── worker.py # 异构worker基础代码,每个worker创建后配置为ray actor
│ ├── distComm.py # 分布式通信代码,专职于分布式计算的通信(基于gloo,nccl等),与ray网络通信不同
│ ├── ops.py # 异构算子搭建
│ └── __init__.py # python模块初始化
├── models # 神经网络分布式计算执行-基于heterogeneous_serve.ops
│ └── qwen35.py # qwen3.5-0.8B模型,测试用
├── localDev # 本地测试异构框架代码运行环境搭建,采用双容器运行模仿双节点的ray网络运行计算服务
│ ├── Dockerfiles # 容器镜像创建脚本
│ ├── requirements.txt # 容器搭建所需的环境安装,与根目录下的requirements.txt有些许差异,专用于容器中的环境安装
│ └── docker-compose-compCluster.yaml # docker compose脚本,创建双容器ray网络测试异构计算框架,注意修改脚本中的源码挂载目录和cpuset设置
├── analyze_model.py # ai分析safetensor文件,生成model.qwen35.py文件
├── model_analysis.md # 模型分析结果的文档体现
├── server.py # 启动异构计算ray服务器,只提供算子的直接调用功能,测试用
├── server_LLMgenerate.py # 启动qwen3.5-0.8B模型推理服务器,包含神经网络推理所需的worker,dispatcher相关调度函数实现
├── client.py # 客户端请求服务功能,对应server.py,测试用
├── client_LLMgenerate.py # 客户端请求服务功能,对应server_LLMgenerate.py
├── Images # 文档所需图像存储
│ ├── 异构软件框架.drawio
│ └── 异构软件框架.svg
├── README.md # 本文件
├── AGENTS.md # AI agents 参与vibe coding的证据
└── requirements.txt # 框架安装所需环境
本项目现阶段处于初步开发阶段,基础的开发步骤如下,欢迎尝试:
-
构建自己的计算服务: 仿照server.py / server_LLMgenerate.py书写自己的dispatcher,worker计算服务(如服务较为复杂,例如模型推理,参见models/qwen35.py,供server_xxx.py调用);
-
本地测试计算正确性:
- 确保Dockerfiles和requirements.txt在同一目录下,使用docker build创建测试的容器镜像;
- 容器镜像创建完成后,使用docker compose脚本搭建一个双容器ray网络测试环境(默认全部使用cpu进行计算),注意修改源码的挂载路径,以及cpuset的设置;
- 在测试环境中验证你的计算服务的结果正确性,启动服务时注意使用--device cpu0,cpu1即可创建2个worker并部署到2个容器节点(注意如果采用cpu计算,测试环境中时间统计受cpu的底层系统及其他程序的调度影响会出现较大的跳动,仅供参考)。
-
实际部署异构ray网络测试:将程序框架部署到实际的异构ray网络中进行测试,注意heterogeneous_server.distComm提供底层通信时间和通信数据量的统计,供测试分析。
Qwen3.5-0.8B(混合架构:18 × Gated DeltaNet 线性注意力 + 6 × GQA 全注意力,SwiGLU MLP)
的全部计算映射到 ops.py 的注册算子(linear / rms_norm / rms_norm_gated / swiglu /
causal_conv1d / causal_conv1d_update / l2norm / gated_delta_rule / apply_rotary /
repeat_kv / causal_attention / sigmoid / embedding / sample_token),
由 qwen35.py 组装成完整前向。模型算子重构源码位于/models/qwen35.py,Dispatcher及Worker针对网络推理的相关功能重构见源码server_LLMgenerate.py。
┌──────────────────────────────────────────┐
HTTP 请求 → │ Dispatcher /generate │
│ 分词 → prefill → 逐 token 解码 → 采样 │
└───────┬──────────────┬────────────────────┘
隐状态沿流水线传递(每设备一个层区间)
┌───────▼────────┐ ┌─▼─────────────┐
│ worker-cpu │ │ worker-... │ 每个 DeviceWorker 只加载自己的
│ layers [0, n) │ │ layers [n,24) │ 层分片,逐层 cache 留在本地
└────────────────┘ └───────────────┘
heterogeneous_serve/qwen35.py— 权重加载(safetensors)+ 基于注册算子的模型前向/生成analyze_model.py— 解析 safetensors 权重结构,生成算子映射报告(model_analysis.md)server_LLMgenerate.py—实现模型切片,模型推理调度设计以及服务启动;client_generate.py—/generateHTTP 客户端
# 分析模型并生成算子映射报告
python3 analyze_model.py --model-dir ../Qwen3.5-0.8B -o model_analysis.md
# 起推理服务(测试环境中,模型权重挂载在/workspace/models)
python3 server_LLMgenerate.py --ray-address auto --model-dir /workspace/models --devices cpu0,cpu1 --tp-size 2 --host 0.0.0.0 --port 8000 #--model-dir 需指向模型参数路径,--tp-size tensor parallelism模型切割数量, --host/port 启动服务的网络配置
python3 client_LLMgenerate.py --prompt "The capital of France is" --max-new 20 #client测试- 新算子:在
ops.py中加一个@register_op("my_op")装饰的函数即可,无需改其他代码。 - 新型计算:扩展设备的
compute配置(DeviceConfig.compute)并在DeviceWorker中接入对应执行路径,启动 server 时按设备注入。 - 新设备类型:在
device.py的探测/解析逻辑和config.py的ray_actor_options()中各加一个分支。 - 多副本/多节点:调大
DeviceConfig.replicas,Ray 会自动把副本调度到有空闲对应资源的节点。