引言:数据进得来,才算得动
大规模数据采集常被目标站点限流、封 IP、验证码拦截。企业级代理 IP 服务如 亿牛云可让采集在分布式节点间平滑切换出口,保障数据稳定入库。数据进来后,瓶颈转向算力——下面用代码直接对比 CuPy、Numba、PyTorch 三种上 GPU 的方式。
- 环境准备
- CuPy:把 Numpy 代码搬上 GPU
1.1 逐行迁移
1.2 正确的 GPU 计时(别用 time.time)
1.3 显存与 DLPack 零拷贝互转 - Numba:JIT 编译与手写 CUDA 内核
2.1 CPU 加速:@njit
2.2 GPU 内核:@cuda.jit(手动排布 grid/block)
2.3 声明式并行:@vectorize(免手写内核) - PyTorch:张量 + 自动微分 + AMP
3.1 张量上 GPU 与反向传播
3.2 混合精度训练(AMP)压显存提速度
3.3 导出推理图(脱离训练环境)
```import torch
class Net(torch.nn.Module):
def forward(self, x):
return x * 2 + 1
ep = torch.export.export(Net(), (torch.randn(4, 4, device='cuda'),))
print(ep.graph_module) # 可序列化,便于部署
4. 三者串联:CuPy 预处理 + PyTorch 训练
```import cupy as cp, torch
from torch.utils.data import TensorDataset, DataLoader
# 1) CuPy 做向量化特征工程(留在显存)
raw = cp.random.rand(1_000_000, 64)
feat = (raw - raw.mean(axis=0)) / raw.std(axis=0) # 标准化
feat = cp.ascontiguousarray(feat)
# 2) DLPack 零拷贝交给 PyTorch
x = torch.from_dlpack(feat) # 不回主机
y = torch.randn(1_000_000, 1, device='cuda')
loader = DataLoader(TensorDataset(x, y), batch_size=4096, shuffle=True)
net = torch.nn.Sequential(torch.nn.Linear(64, 1)).cuda()
opt = torch.optim.Adam(net.parameters())
for xb, yb in loader:
opt.zero_grad()
loss = torch.nn.functional.mse_loss(net(xb), yb)
loss.backward(); opt.step()
- 决策速查
```def recommend(use_case: str) -> str:
return {
}.get(use_case, "先量化瓶颈在带宽还是算力")"已有 numpy 代码想提速": "CuPy(改 import)", "自定义循环/分支算法": "Numba(@njit 或 @cuda.jit)", "深度学习/需求导": "PyTorch", "预处理+训练混合": "CuPy 预处理 + PyTorch 训练",
```
维度
CuPy
Numba
PyTorch
上手
极低
中
中高
自动微分
否
否
是
控制流
低
高
中
最佳
向量化数值
自定义循环
梯度/训练
选型铁律:用 cupy.cuda.Event / torch.cuda.Event 测真实 GPU 耗时,首跑丢弃(冷启动),并把 cpu→gpu 拷贝计入总账——小数据下 GPU 可能更慢。