在 cuda 基础环境中安装完整的cupy
依赖版本参考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))
![]()
更多推荐
所有评论(0)