依赖版本参考Installation — CuPy 13.4.1 documentation

1.  安装 cupy的依赖和cupy

1.0. 创建 cuda 基础容器

export NUM=2 && \
sudo docker run --gpus all -it \
--name cupy_LHL_${NUM} \
-v /home/jimmy/ex_cupy/tmp${NUM}:/root/tmp${NUM} \
-v /home/jimmy/.ssh:/root/.ssh \
nvidia/cuda:12.6.3-devel-ubuntu22.04

1.1. 安装 python 3.10

3.12 有一点不兼容的bug。

在第0步中创建的新容器中,运行如下脚本:

   apt update
   apt install git wget
   apt install build-essential

   apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev libbz2-dev liblzma-dev
   git clone https://github.com/python/cpython.git
   cd cpython/
   git checkout v3.10.12


   ./configure \
--enable-shared \
--enable-ipv6 \
--with-ensurepip=install \
--with-system-expat \
--with-system-ffi \
--with-system-libmpdec \
--enable-loadable-sqlite-extensions \
--with-dbmliborder=bdb:gdbm \
--with-computed-gotos \
--with-ensurepip=install \
--with-fpectl \
--with-address-sanitizer \
--prefix=/usr \
--enable-optimizations

   make -j
   make install
   /usr/local/bin/python3 --version
   /usr/local/bin/pip3 --version
   update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3 100
   update-alternatives --config python3 
   echo "/usr/local/lib" |  tee /etc/ld.so.conf.d/python3.conf
   ldconfig

保存为 helloPython.sh

bash ./helloPython.sh

完成安装。

1.2. 安装 cutensor


Install cutensor:

wget https://developer.download.nvidia.com/compute/cutensor/redist/libcutensor/linux-x86_64/libcutensor-linux-x86_64-2.0.0.7-archive.tar.xz

tar xf libcutensor-linux-x86_64-2.0.0.7-archive.tar.xz

cd libcutensor/

cp include/* /usr/include/
cp lib/* /usr/lib/x86_64-linux-gnu/

ldconfig

保存为 helloCutensor.sh,

bash ./helloCutensor.sh

完成安装。

注:
安装最新的 cutensor,cupy 并非必须。

wget https://developer.download.nvidia.com/compute/cutensor/2.2.0/local_installers/cutensor-local-repo-ubuntu2204-2.2.0_1.0-1_amd64.deb
dpkg -i cutensor-local-repo-ubuntu2204-2.2.0_1.0-1_amd64.deb
cp /var/cutensor-local-repo-ubuntu2204-2.2.0/cutensor-*-keyring.gpg /usr/share/keyrings/
apt-get update
apt-get -y install libcutensor2 libcutensor-dev libcutensor-doc

1.3. 安装 cusparseLt

Install cusparseLt:
当前cupy新版本,对 cusparslt的版本要求比较低,0.2版本。如果安装新版本 0.7 的话,会有不兼容的函数名。

wget https://developer.download.nvidia.com/compute/libcusparse-lt/0.2.0/local_installers/libcusparse_lt-linux-x86_64-0.2.0.1.tar.gz
tar xf libcusparse_lt-linux-x86_64-0.2.0.1.tar.gz
cd libcusparse_lt
  cp include/cusparseLt.h /usr/include/
  cp lib64/libcusparseLt* /usr/lib/x86_64-linux-gnu/
ldconfig

保存为 helloCusparseLt.sh

bash ./helloCusparseLt.sh

完成安装。

注:

如下步骤为安装最新版本的 cusparseLt,本cupy用不到

wget https://developer.download.nvidia.com/compute/cusparselt/0.7.1/local_installers/cusparselt-local-repo-ubuntu2204-0.7.1_1.0-1_amd64.deb
sudo dpkg -i cusparselt-local-repo-ubuntu2204-0.7.1_1.0-1_amd64.deb
sudo cp /var/cusparselt-local-repo-ubuntu2204-0.7.1/cusparselt-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install libcusparselt0 libcusparselt-dev

1.4. 安装 cudnn

通过登陆 nvidia 开发者网站,预先下载文件:

cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz 

   tar xf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz 
   cd cudnn-linux-x86_64-8.9.7.29_cuda12-archive
   cd include/
   cp cudnn*.h /usr/local/cuda/include/
   cd ../lib/
   cp libcudnn* /usr/local/cuda/lib64/
   chmod a+r /usr/local/cuda/include/cudnn*.h
   ldconfig

  pip3 install numpy
  pip3 install scipy==1.14.0
  pip3 install optuna==4.0.0
  pip3 install setuptools

注:版本参考Installation — CuPy 13.4.1 documentation

与 cudnn-linux-xxxxx.tar.xz 同文件夹下创建 hellocudnn.sh,并运行:

bash ./hellocudnn.sh

完成安装cudnn8.

注:

下边的方式是安装最新版本的 cudnn,但是当前的 cupy 没有支持到 cudnn9,cudnn8正好,

wget https://developer.download.nvidia.com/compute/cudnn/9.10.2/local_installers/cudnn-local-repo-ubuntu2204-9.10.2_1.0-1_amd64.deb
sudo dpkg -i cudnn-local-repo-ubuntu2204-9.10.2_1.0-1_amd64.deb
sudo cp /var/cudnn-local-repo-ubuntu2204-9.10.2/cudnn-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cudnn

1.5. 安装 nccl

如果显卡是 A100,则用80;

如果是 rtx 2080,75; V100 为 70。

  git clone https://github.com/NVIDIA/nccl.git
  apt install build-essential devscripts debhelper fakeroot
  cd nccl/
  git checkout v2.25.1-1
  make -j src.build NVCC_GENCODE="-gencode=arch=compute_80,code=sm_80"
  make pkg.debian.build
  dpkg -i build/pkg/deb/libnccl2_2.25.1-1+cuda12.6_amd64.deb 
  dpkg -i build/pkg/deb/libnccl-dev_2.25.1-1+cuda12.6_amd64.deb 

1.6 其他依赖
 

sudo python -m pip install -U setuptools pip

sudo pip install numpy==2.1.3  -i https://pypi.tuna.tsinghua.edu.cn/simple
sudo pip install scipy==1.14.1  -i https://pypi.tuna.tsinghua.edu.cn/simple
sudo pip install optuna==4.2.1  -i https://pypi.tuna.tsinghua.edu.cn/simple

1.7. 下载cupy 源码并安装 cupy

下载:

git clone https://github.com/cupy/cupy.git
cd cupy
git branch
git checkout v13.4.1
git branch
git submodule update --init

安装:

pip3 -v install --use-pep517 .

2.  编译 cupy的记录

pip3 -v install . 的控制台输出信息

import cupy

3. 验证示例

3.1. 数组

import cupy as cp
import numpy as np

# 创建 CuPy 数组
x = cp.arange(10)  # 在 GPU 上创建数组
y = cp.ones((5, 5))

print("CuPy 数组:", x)
print("数组形状:", y.shape)

# 基本的数学运算
a = cp.array([1, 2, 3])
b = cp.array([4, 5, 6])

c = a + b  # 逐元素加法
d = cp.sin(a)  # 三角函数
e = cp.dot(a, b)  # 点积

print("加法结果:", c)
print("正弦结果:", d)
print("点积结果:", e)

# 与 NumPy 数组转换
numpy_array = np.array([1, 2, 3])
cupy_array = cp.asarray(numpy_array)  # NumPy → CuPy
back_to_numpy = cp.asnumpy(cupy_array)  # CuPy → NumPy
print(back_to_numpy)

3.2 矩阵乘法

import cupy as cp
import numpy as np
import time

# 大规模矩阵乘法性能对比
#size =3 
size = 8192 

# CPU (NumPy)
start = time.time()

a_np = np.random.rand(size, size)
b_np = np.random.rand(size, size)
#print("a=", a_np)
#print("b=", b_np)

result_np = np.dot(a_np, b_np)
cpu_time = time.time() - start
#print("result_np=", result_np)


# GPU (CuPy)
start = time.time()

#a_gpu = cp.random.rand(size, size)
a_gpu = cp.array(a_np)
#b_gpu = cp.random.rand(size, size)
b_gpu = cp.array(b_np)
result_gpu = cp.dot(a_gpu, b_gpu)


cp.cuda.Stream.null.synchronize()  # 等待 GPU 完成
gpu_time = time.time() - start

#print("a_gpu=", a_gpu)

print(f"CPU 时间: {cpu_time:.3f} 秒")
print(f"GPU 时间: {gpu_time:.3f} 秒")
print(f"加速比: {cpu_time/gpu_time:.1f}x")

# 验证结果正确性
result_gpu_np = cp.asnumpy(result_gpu)
print("结果差异:", np.max(np.abs(result_np - result_gpu_np)))

3.3 简单的逐元素 cuda kernel

import cupy as cp
import numpy as np

# 简单的逐元素加法内核
add_kernel = cp.ElementwiseKernel(
    'float32 x, float32 y',  # 输入参数
    'float32 z',             # 输出参数
    'z = x + y',             # 计算操作
    'add_kernel'             # 内核名称
)

# 使用示例
x = cp.arange(10, dtype=cp.float32)
y = cp.ones(10, dtype=cp.float32) * 2
z = cp.empty_like(x)

print("x=", x.get())
print("y=", y.get())
print("z=", z.get())

add_kernel(x, y, z)
print("z = x+y=",z.get())
#print("加法结果:", z.g())

3.4 另一个逐元素 cuda kernel

import cupy as cp
import time

# 向量点积内核
dot_product_kernel = cp.ElementwiseKernel(
    'float32 x, float32 y, float32 alpha',
    'float32 z',
    'z = alpha * x * y',
    'dot_product_kernel'
)

# 性能对比
size = 1000000
x = cp.random.rand(size).astype(cp.float32)
y = cp.random.rand(size).astype(cp.float32)
alpha = 0.5
result = cp.empty_like(x)

# 使用自定义内核
start = time.time()
dot_product_kernel(x, y, alpha, result)
cp.cuda.Stream.null.synchronize()
kernel_time = time.time() - start

# 使用内置操作
start = time.time()
result_builtin = alpha * x * y
cp.cuda.Stream.null.synchronize()
builtin_time = time.time() - start

print(f"内核时间: {kernel_time:.6f}s")
print(f"内置操作时间: {builtin_time:.6f}s")
print(f"结果一致性: {cp.allclose(result, result_builtin)}")

3.5 reduction kernel 

import cupy as cp

# 求和归约内核
sum_kernel = cp.ReductionKernel(
    'float32 x',      # 输入
    'float32 y',      # 输出
    'x',              # 映射操作
    'a + b',          # 归约操作
    'y = a',          # 后处理
    '0',              # 初始值
    'sum_kernel'      # 内核名称
)

# 使用示例
data = cp.arange(100, dtype=cp.float32)
result = sum_kernel(data)
print("数组求和:", result.get())
print("验证结果:", cp.sum(data).get())

3.6 自定义 raw kernel

import cupy as cp

# 使用原始 CUDA C++ 代码
matrix_mult_kernel = cp.RawKernel(r'''
extern "C" __global__
void matrix_mult(const float* A, const float* B, float* C, 
                 int M, int N, int K) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    
    if (row < M && col < K) {
        float sum = 0.0f;
        for (int i = 0; i < N; i++) {
            sum += A[row * N + i] * B[i * K + col];
        }
        C[row * K + col] = sum;
    }
}
''', 'matrix_mult')

# 使用示例
M, N, K = 256, 256, 256
A = cp.random.rand(M, N).astype(cp.float32)
B = cp.random.rand(N, K).astype(cp.float32)
C = cp.zeros((M, K), dtype=cp.float32)

# 配置线程块和网格
block_size = (16, 16)
grid_size = ((K + block_size[0] - 1) // block_size[0], 
             (M + block_size[1] - 1) // block_size[1])

matrix_mult_kernel(grid_size, block_size, (A, B, C, M, N, K))

# 验证结果
C_builtin = cp.dot(A, B)
print("结果一致性:", cp.allclose(C, C_builtin, atol=1e-4))

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐