Progressive Multitask是渐进式多任务神经网络,它可以实现分类任务和回归任务。该模型在药物发现、材料科学和计算化学等任务中展现出强大能力,本文描述的Progressive Multitask模型是基于DeepChem套件实现的,后续适配也是基于该套件修改。
| 组件 | 版本 |
|---|---|
| Python | 3.10.19 |
| PyTorch | 2.1.0 |
| torch_npu | 2.1.0.post13 |
| CANN | 8.1.RC1 |
| 设备型号 | NPU 配置 |
|---|---|
| Atlas 800T A2 | 单卡 / 多卡 |
| 镜像环境 | 镜像地址 |
|---|---|
| 公网 | swr.cn-southwest-2.myhuaweicloud.com/atelier/pytorch_2_1_ascend:pytorch_2.1.0-cann_8.1.rc1-py_3.10-euler_2.10.11-aarch64-snt9b-20250603154214-4e60e43 |
docker run -u root --privileged \
--name {container_name} \
--device /dev/davinci0 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-itd {image_id} /bin/bashdocker exec -it {container_name} bash直接安装deepchem-ascend二进制包,已基于适配代码重新编译成二进制包上传pypi
pip install deepchem-ascend==0.0.1安装运行必要的依赖库
pip install torch-geometric测试代码举例如下:
import numpy as np
import deepchem as dc
import tempfile
import os
try:
import torch
import torch.nn as nn
from deepchem.models.torch_models import ProgressiveMultitaskRegressor, ProgressiveMultitaskClassifier
has_torch = True
except ModuleNotFoundError:
has_torch = False
pass
n_tasks = 2
n_features = 12
torch_model = ProgressiveMultitaskRegressor(
n_tasks=n_tasks,
n_features=n_features,
layer_sizes=[128, 256],
alpha_init_stddevs=0.02,
weight_init_stddevs=0.02,
dropouts=0,
)
weights = np.load(
os.path.join(os.path.dirname(__file__), "assets",
"progressive-multitask-regressor-sample-weights.npz"))
# Determine if torch_model is a DeepChem TorchModel or raw nn.Module
if hasattr(torch_model, 'model'):
# DeepChem's TorchModel wraps the actual nn.Module in .model
nn_model = torch_model.model
else:
# Assume it's already an nn.Module
nn_model = torch_model
# Get the device of the model (e.g., 'npu:0' or 'cpu')
device = next(nn_model.parameters()).device
def to_tensor_on_device(np_array):
"""Convert numpy array to torch tensor on the model's device."""
return torch.from_numpy(np_array).to(device)
# === Load layer weights for task 0 ===
nn_model.layers[0][0].weight.data.copy_(to_tensor_on_device(weights["layer-0-0-w"]))
nn_model.layers[0][0].bias.data.copy_(to_tensor_on_device(weights["layer-0-0-b"]))
nn_model.layers[0][1].weight.data.copy_(to_tensor_on_device(weights["layer-0-1-w"]))
nn_model.layers[0][1].bias.data.copy_(to_tensor_on_device(weights["layer-0-1-b"]))
nn_model.layers[0][2].weight.data.copy_(to_tensor_on_device(weights["layer-0-2-w"]))
nn_model.layers[0][2].bias.data.copy_(to_tensor_on_device(weights["layer-0-2-b"]))
# === Load layer weights for task 1 ===
nn_model.layers[1][0].weight.data.copy_(to_tensor_on_device(weights["layer-1-0-w"]))
nn_model.layers[1][0].bias.data.copy_(to_tensor_on_device(weights["layer-1-0-b"]))
nn_model.layers[1][1].weight.data.copy_(to_tensor_on_device(weights["layer-1-1-w"]))
nn_model.layers[1][1].bias.data.copy_(to_tensor_on_device(weights["layer-1-1-b"]))
nn_model.layers[1][2].weight.data.copy_(to_tensor_on_device(weights["layer-1-2-w"]))
nn_model.layers[1][2].bias.data.copy_(to_tensor_on_device(weights["layer-1-2-b"]))
# === Load adapter weights and alphas ===
# Task 1 adapter 0
nn_model.alphas[0][0].data.copy_(to_tensor_on_device(weights["alpha-0-0"]))
nn_model.adapters[0][0][0].weight.data.copy_(to_tensor_on_device(weights["adapter-0-0-0-w"]))
nn_model.adapters[0][0][0].bias.data.copy_(to_tensor_on_device(weights["adapter-0-0-0-b"]))
nn_model.adapters[0][0][1].weight.data.copy_(to_tensor_on_device(weights["adapter-0-0-1-w"]))
# Task 1 adapter 1
nn_model.alphas[0][1].data.copy_(to_tensor_on_device(weights["alpha-0-1"]))
nn_model.adapters[0][1][0].weight.data.copy_(to_tensor_on_device(weights["adapter-0-1-0-w"]))
nn_model.adapters[0][1][0].bias.data.copy_(to_tensor_on_device(weights["adapter-0-1-0-b"]))
nn_model.adapters[0][1][1].weight.data.copy_(to_tensor_on_device(weights["adapter-0-1-1-w"]))
input_x = weights["input"]
output = weights["output"]
# Inference using TorchModel's predict() method works with NumpyDataset only. Hence we need to convert our numpy arrays to NumpyDataset.
y = np.random.rand(input_x.shape[0], 1)
w = np.ones((input_x.shape[0], 1))
ids = np.arange(input_x.shape[0])
input_x = dc.data.NumpyDataset(input_x, y, w, ids)
torch_out = torch_model.predict(input_x)
print(f"模型所在设备: {device}")测试结果: