
显卡的核心是图形处理器,也就是我们常说的GPU,全称Graphics Processing Unit,它和 CPU 的本质区别是并行计算架构,CPU 擅长复杂的串行逻辑,GPU 则通过海量的计算核心,主攻高吞吐量的并行任务,比如大模型推理、图形渲染、深度学习训练。理解 GPU 底层原理,是搞懂大模型算力优化的关键。
GPU 的架构设计围绕“大规模并行”展开,是并行计算的硬件基础,我们先了解其核心组件及作用;

对大模型算力的影响:
对大模型算力的影响:
对大模型算力的影响:
对大模型算力的影响:
数据流完整路径优化:
大模型专用优化策略:
实际部署场景考量:
特性 | CPU | GPU |
|---|---|---|
核心数量 | 少(4-64 核) | 极多(数千到数万 CUDA 核心) |
缓存大小 | 大(MB 到 GB 级) | 小(KB 到 MB 级) |
擅长任务 | 复杂串行逻辑(如操作系统调度、业务代码) | 简单并行任务(如矩阵乘法、向量运算) |
适用场景 | 通用计算 | 大模型训练 / 推理、图形渲染、科学计算 |
类比理解:
核心结论:
GPU 算力的底层来自于指令执行与并行计算,大模型的核心运算是矩阵乘法(如 Transformer 的 QKV 矩阵运算),GPU 之所以能高效处理,靠的是三层并行机制:
GPU 的最小执行单元是线程(Thread),多个线程组成线程块(Block),多个线程块组成网格(Grid)。
GPU 的 SM 支持单指令多数据(SIMT)架构,同一个 SM 内的所有 CUDA 核心,同时执行同一条指令,但处理不同的数据。
NVIDIA 的张量核心专门为混合精度计算设计,支持 FP16、INT8、INT4 等低精度运算:
算力释放的关键在于软件与硬件的协同,GPU 的理论算力(如 RTX 4090 FP32 算力 83 TFLOPS)只是纸面参数,实际算力释放取决于软件层的适配,这也是大模型算力优化的核心:
CUDA(Compute Unified Device Architecture)是 NVIDIA 提供的 GPU 编程框架,是软件调用 GPU 算力的 “桥梁”:
CUDA 核心是 GPU 的最小计算工人,RTX4090有16384个CUDA 核心,每个 CUDA 核心一次能算 1 个简单运算(比如1+2、3×4),16384 个核心同时算,就能秒算上万次简单运算。
计算示例:并行计算 1000 个加法
1+1, 2+1, 3+1...1000+1,要依次算 1000 次,总耗时 0.00毫秒;
哪怕是 1000 个简单加法,GPU 的并行优势也能体现,核心数量越多,并行任务越多,优势越明显,比如算 100 万个加法,提升倍数会到上千倍。
张量核心是 GPU 专门为矩阵乘法设计的超级工人,普通 CUDA 核心一次算 1 个乘法,张量核心一次能算4×4矩阵 × 4×4矩阵,是大模型推理/训练的算力发动机。 大模型的 Transformer 架构,核心就是QKV 矩阵乘法,比如:
计算示例:张量核心算矩阵乘法

1×5 + 2×6 + 3×7 + 4×8,分 4 次乘法 + 3 次加法;70。
张量核心对矩阵乘法的加速是量级的,大模型有上千个这样的矩阵乘法,启用张量核心后,整体算力能提升数倍,这也是为什么大模型优化必须确保张量核心被激活。
显存是 GPU 的数据仓库,用来存:
核心指标:
计算示例:显存带宽对算力的影响 假设要算14B 模型 INT4 量化推理:

GPU 驱动是操作系统与 GPU 硬件的接口,负责:
深度学习框架(如 PyTorch、TensorFlow)会对代码进行底层优化,让大模型运算更适配 GPU:
在大模型推理时,经常遇到 “显卡算力高但利用率低” 的问题,底层原因主要有 3 类:
以大模型推理的 QKV 矩阵乘法为例,拆解 GPU 的并行过程,就像工厂流水线:

步骤 1:任务拆分(CPU→GPU) CPU 把Q×K^T这个大任务,拆成无数个4×4 小矩阵乘法以适配张量核心,比如:
步骤 2:并行计算(GPU 内部)
步骤 3:结果合并(GPU→CPU)
步骤详解:
计算特点:
追踪数据从 CPU 传到 GPU→GPU 计算→结果传回 CPU的完整耗时,用条形图对比各阶段占比,直观看到 GPU 计算的时间分布。
import torch
import time
import matplotlib.pyplot as plt
import numpy as np
# ====================== 1. 初始化配置 ======================
# 模拟大模型推理的矩阵大小(14B模型注意力层常见维度)
BATCH_SIZE = 32
SEQ_LEN = 512
HIDDEN_SIZE = 128
# 确保使用GPU
assert torch.cuda.is_available(), "需要NVIDIA GPU(支持CUDA)才能运行"
device = torch.device("cuda:0")
# ====================== 2. 追踪各阶段耗时 ======================
# 生成模拟数据(Q/K/V矩阵)
q_cpu = torch.randn(BATCH_SIZE, SEQ_LEN, HIDDEN_SIZE, dtype=torch.float16)
k_cpu = torch.randn(BATCH_SIZE, SEQ_LEN, HIDDEN_SIZE, dtype=torch.float16)
# 阶段1:CPU → GPU 数据传输耗时
start_trans = time.time()
q_gpu = q_cpu.to(device, non_blocking=True)
k_gpu = k_cpu.to(device, non_blocking=True)
torch.cuda.synchronize() # 等待传输完成
trans_time = (time.time() - start_trans) * 1000 # 转毫秒
# 阶段2:GPU计算(Q×K^T,大模型注意力层核心运算)
start_calc = time.time()
# 转置K矩阵(注意力层标准操作)
k_t_gpu = k_gpu.transpose(1, 2)
# 矩阵乘法(张量核心加速)
attn_scores = torch.matmul(q_gpu, k_t_gpu)
torch.cuda.synchronize() # 等待计算完成
calc_time = (time.time() - start_calc) * 1000
# 阶段3:GPU → CPU 结果传输耗时
start_back = time.time()
attn_scores_cpu = attn_scores.cpu()
back_time = (time.time() - start_back) * 1000
# 总耗时
total_time = trans_time + calc_time + back_time
# ====================== 3. 可视化各阶段耗时占比 ======================
plt.rcParams['font.sans-serif'] = ['SimHei'] # 支持中文
plt.rcParams['axes.unicode_minus'] = False
# 数据准备
labels = ['CPU→GPU传输', 'GPU计算', 'GPU→CPU传输']
times = [trans_time, calc_time, back_time]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
# 计算占比
percentages = [round(t/total_time*100, 1) for t in times]
# 绘制堆叠条形图+饼图(双视角)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
# 子图1:条形图(绝对耗时)
bars = ax1.bar(labels, times, color=colors, width=0.6)
ax1.set_title('GPU计算全流程耗时对比', fontsize=14, fontweight='bold')
ax1.set_ylabel('耗时(毫秒)', fontsize=12)
# 标注数值和占比
for bar, t, p in zip(bars, times, percentages):
ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height()+0.1,
f'{t:.2f}ms\n({p}%)', ha='center', fontweight='bold')
ax1.grid(axis='y', alpha=0.3)
# 子图2:饼图(占比)
wedges, texts, autotexts = ax2.pie(times, labels=labels, colors=colors,
autopct='%1.1f%%', startangle=90)
ax2.set_title('GPU计算全流程耗时占比', fontsize=14, fontweight='bold')
# 美化饼图文字
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
plt.tight_layout()
plt.savefig('gpu_calc_process_time.png', dpi=300, bbox_inches='tight')
plt.close()
# ====================== 4. 输出关键信息 ======================
print("=== GPU计算过程耗时分析 ===")
print(f"CPU→GPU传输耗时:{trans_time:.2f} ms(占比 {percentages[0]}%)")
print(f"GPU计算耗时:{calc_time:.2f} ms(占比 {percentages[1]}%)")
print(f"GPU→CPU传输耗时:{back_time:.2f} ms(占比 {percentages[2]}%)")
print(f"总耗时:{total_time:.2f} ms")
print("\n核心结论:GPU计算本身很快,耗时主要在数据传输!")
print("优化方向:减少CPU-GPU数据传输(比如数据常驻GPU、批量计算)")输出结果:
=== GPU计算过程耗时分析 === CPU→GPU传输耗时:2.35 ms(占比 28.1%) GPU计算耗时:4.52 ms(占比 54.0%) GPU→CPU传输耗时:1.49 ms(占比 17.9%) 总耗时:8.36 ms 核心结论:GPU计算本身很快,耗时主要在数据传输! 优化方向:减少CPU-GPU数据传输(比如数据常驻GPU、批量计算)
结果图示:

用热力图展示“GPU 线程块(Block)× 线程(Thread)”的并行任务分配,直观看到大任务如何拆成小任务,分给不同 GPU 核心。
import torch
import matplotlib.pyplot as plt
import numpy as np
# ====================== 1. 模拟GPU任务拆分逻辑 ======================
# 大矩阵大小:128×128(拆成16×16个8×8小矩阵)
BIG_MATRIX_SIZE = 128
SMALL_BLOCK_SIZE = 8
NUM_BLOCKS = BIG_MATRIX_SIZE // SMALL_BLOCK_SIZE # 16个Block
# 生成模拟任务:每个Block负责一个8×8小矩阵的乘法
# 用热力图颜色表示Block的计算负载(颜色越深,负载越高)
task_load = np.zeros((NUM_BLOCKS, NUM_BLOCKS))
# 模拟大模型注意力层的负载分布:中心Block负载更高
for i in range(NUM_BLOCKS):
for j in range(NUM_BLOCKS):
# 距离中心越近,负载越高(模拟注意力层的聚焦特性)
dist = np.sqrt((i - NUM_BLOCKS/2)**2 + (j - NUM_BLOCKS/2)**2)
task_load[i, j] = 100 - dist * 5 # 负载范围:50-100%
# ====================== 2. 可视化任务拆分 ======================
plt.rcParams['font.sans-serif'] = ['SimHei']
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
# 子图1:GPU Block任务分配热力图
im = ax1.imshow(task_load, cmap='RdYlBu_r', vmin=0, vmax=100)
ax1.set_title('GPU线程块(Block)任务负载分布', fontsize=14, fontweight='bold')
ax1.set_xlabel('Block列索引', fontsize=12)
ax1.set_ylabel('Block行索引', fontsize=12)
# 添加网格(分隔8×8小矩阵)
for i in range(1, NUM_BLOCKS):
ax1.axhline(y=i-0.5, color='white', linewidth=0.5)
ax1.axvline(x=i-0.5, color='white', linewidth=0.5)
# 颜色条
cbar1 = plt.colorbar(im, ax=ax1)
cbar1.set_label('Block负载(%)', fontsize=12)
# 子图2:并行计算逻辑示意图
ax2.text(0.1, 0.8, '大矩阵(128×128)', fontsize=12, fontweight='bold', transform=ax2.transAxes)
ax2.text(0.3, 0.8, '→', fontsize=14, transform=ax2.transAxes)
ax2.text(0.4, 0.8, '拆分16×16个8×8小矩阵', fontsize=12, fontweight='bold', transform=ax2.transAxes)
ax2.text(0.7, 0.8, '→', fontsize=14, transform=ax2.transAxes)
ax2.text(0.8, 0.8, 'GPU 16×16个Block并行计算', fontsize=12, fontweight='bold', transform=ax2.transAxes)
# 绘制拆分示意图
for i in range(4):
for j in range(4):
x = 0.2 + j*0.1
y = 0.2 + i*0.1
ax2.add_patch(plt.Rectangle((x, y), 0.08, 0.08,
facecolor='#4ECDC4', alpha=0.5, edgecolor='black'))
ax2.text(x+0.04, y+0.04, f'Block\n{i},{j}', ha='center', va='center', fontsize=8)
ax2.set_xlim(0, 1)
ax2.set_ylim(0, 1)
ax2.axis('off')
ax2.set_title('GPU并行任务拆分逻辑', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig('gpu_parallel_task_split.png', dpi=300, bbox_inches='tight')
plt.close()
print("GPU并行计算的核心逻辑:")
print(f"1. 把{BIG_MATRIX_SIZE}×{BIG_MATRIX_SIZE}的大矩阵拆成{NUM_BLOCKS}×{NUM_BLOCKS}个小矩阵;")
print("2. 每个小矩阵分配给一个GPU Block(线程块);")
print("3. 所有Block同时计算,实现并行加速。")输出结果:
GPU并行计算的核心逻辑: 1. 把128×128的大矩阵拆成16×16个小矩阵; 2. 每个小矩阵分配给一个GPU Block(线程块); 3. 所有Block同时计算,实现并行加速。
结果图示:

GPU 计算过程可视化是理解硬件并行逻辑、定位算力瓶颈、优化大模型性能的关键手段,其核心价值在于将 GPU黑盒式的运算过程转化为直观可量化的图表,既帮技术开发者吃透底层原理,也为工程落地提供数据支撑。
从实现逻辑来看,可视化需围绕“时间、资源、任务”三大核心维度展开:基础层聚焦全流程耗时拆分,清晰暴露数据传输这一高频瓶颈,毕竟 GPU 算得再快,等数据也白搭;进阶层通过实时监控 GPU 核心、张量核心利用率及显存变化,精准判断硬件资源是否物尽其用;高阶层则拆解并行任务分配逻辑,让大任务拆小、多核心并行的底层逻辑不再抽象。
这些可视化方法不仅是学习工具,更是工程优化的实用手段,实际部署大模型时,可通过耗时图表优化数据传输策略,通过资源监控激活张量核心、提升显存带宽利用率,通过任务拆分图表平衡各核心负载。最终实现既懂 GPU 怎么干活,又能针对性让它干得更快、更高效,为企业级大模型推理集群的效能最大化提供支撑。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。