F06|“放到设备”是什么:数据类型、内存、CPU与GPU
从具体对象与小例子开始,理解计算过程与适用条件。
本章目录
数据搬到GPU,改变的是位置而不是含义
“装得下”和“算得快”为什么不是同一回事?
CPU与GPU可先理解成不同的计算场地。数据必须到达实际执行算子的设备,才能参与运算;搬过去并不自动变聪明。数据类型决定每个数怎样存、可表示范围和精度,不能只看“数字还是原来那个数字”。
输入与适用条件:只计算B=2、T=3、d=4的一份编号/特征张量,不计算模型总内存、驱动开销和GPU实测速度。
1 / 4 · 先数对象
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
编号表与特征表不是同一种数据:这里6个整数编号、24个浮点特征。
本步状态由图形与说明共同给出。6×8=48;24×4=96
默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
当速度被搬运限制时,继续加计算核心可能收益很小。
怎样实现
分开数参数、激活、缓存和传输;再测算子与数据传输耗时。
可能的代价与误解
低精度不保证所有算子更快;异步GPU未同步时的计时还会低估真实耗时。
如何判断是否做对
核对字节数、数据类型、设备位置,并用正确的同步方式测量。
同一个数有三种不同的问题
看一份形状[2,3,4]的数据,要分别问:它怎么排列(shape)、每个数怎样存(dtype)、存在哪里并由谁算(device)。这三项不能互相代替。
CPU是执行通用程序的处理器;GPU擅长在合适的运算上并行处理大量数字。设备device是计算框架用来标识执行或存储位置的概念,例如CPU或某块GPU。把数据放到GPU,不会自动使它变得更有语义,只是让相应硬件能够进行后续计算。
整数编号与浮点特征为何类型不同
Token ID用于找表中哪一行,通常采用框架支持的整数类型;Embedding权重和输出常用浮点类型。浮点数是一种用有限位数近似表示含小数数值的方式,它不是任意精度的实数。
int64表示每个整数用64位,即8字节;float32通常每个数用32位,即4字节;FP16和BF16各用16位,即2字节,但指数和有效数字的安排不同,表示范围和精细程度不能只看位数。实际算子支持什么类型,要看具体实现。
改变类型会改变内存与数值误差;改变shape是改变排列解释;改变device是改变执行位置。这些动作不是同一件事。
对较大规模的表示算一遍存储
[2,128]共有256个编号。按int64存储,仅编号数据为256×8=2048字节。
查表结果[2,128,4096]有1,048,576个数。若每个占2字节,仅这份结果为2,097,152字节,即2 MiB。MiB以1024为进制,1 MiB=1024×1024字节;十进制MB则是1,000,000字节。
这不是整个模型只需2 MiB。 E本身、所有层权重、中间结果、KV缓存及运行工作区都还没算。估内存必须列出对象,而不是看到一个张量大小就推断总显存。
一次常见执行的实际顺序
程序先准备模型参数和计算环境,再把本批ID与必要标记交给计算框架。对于独立显存的GPU,需要把参与运算的数据安排到兼容设备上;否则框架可能报设备不一致,而不是自动替你完成所有搬运。
随后调用Embedding操作:根据ID读取权重表对应行,生成本批表示。接着运行网络的矩阵运算。生成结束后,有些结果会被取回CPU用于文本处理或界面显示。
这只是常见逻辑次序,不是所有底层系统都真的进行同样的物理复制。统一内存、模型分片和卸载会改变细节;本课先建立“运算需要访问到数据”的概念。
为什么小任务放GPU有时不快
传输、调度和启动一次运算都有成本。若真正的计算只有几个数字,准备与搬运可能比计算本身还贵。GPU吞吐强,不等于每个小操作延迟都低。
还有一个常见计时陷阱:某些GPU调用是异步的,即CPU发出指令后即可继续,GPU还没做完。只量函数返回时间可能量到“排队指令”的时间,而非计算完成时间。测性能时需要按框架要求等待或使用设备计时机制。
现在把“组批、放设备、查表”连起来
组批解决“这次一起算哪些输入”;补齐和标记解决“不同长度怎么摆”;device解决“在哪里算”;dtype解决“每个数怎样存”;Embedding解决“编号对应哪排数”。每一步的职责都不同,因此每一种错误的排查也不同。
把同一个张量搬到设备,数值和占用如何分别变化
输入与条件。从小例子 [2,3] 的6个整数,查出 [2,3,4] 的24个浮点数。假设ID用int64,每个8字节;浮点输出用FP32,每个4字节。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1算编号存储 | 6×8 | 48字节,只算数据本体。 |
| 2算表示存储 | 24×4 | 96字节;维度和dtype共同决定占用。 |
| 3拷贝到GPU | 把相同数据搬到另一设备 | 形状仍是 [2,3,4];搬运不等于自动增加语义。 |
| 4改用FP16 | 相同24个数,每个2字节 | 本体48字节,但小数可能发生舍入;这与单纯搬设备不同。 |
| 5放大规模 | B=2、T=128、d=4096 | ID有256个整数;输出有1,048,576个数,FP16为2,097,152字节,即2MiB。 |
把过程连起来。先问存几个数,再问每数几字节,最后问在哪个设备;这三件事不能混成一个“维度变大”。
边界与反例。估算不包括张量对象、分配器、模型权重、缓存和中间结果;不是运行整个模型所需显存。
依据与适用范围:[EMBED]。示例输入和场景由本书明确设定。
课后自检
shape[2,3,4]的float32数据本体多少字节?
查看参考答案收起参考答案
把CPU数据搬到GPU会改变Token编号的语义吗?
查看参考答案收起参考答案
延伸阅读:相关系统问题
01|输入究竟是什么:从用户的一句话到模型张量05|训练的一步:从正确标签到参数真正改变
07|KV Cache、FlashAttention与PagedAttention的内部过程
08|推理服务:调度、吞吐、延迟和并行
机制依据:[F-TENSOR][F-EMBED]。本节数值与情景除另注外均为原创教学示例;来源不代替中文讲解。