首页 > 人工智能 > 人工智能 > 从DeepSeek模型谈GPU卡精度运算
本文讲清了“精度—架构—成本”的链路,具有很强的现实意义。不同的GPU卡所支持的浮点精度类型可能差别很大,而且每种类型的卡对不同计算精度类型的算力支持也不一样。作者从不同GPU卡精度支持的情况、适用的场景以及原理等方面详细描述了GPU卡精度运算能力对大模型使用的影响,是提高算力效率的必读知识点。
作者:汪照辉
专注于容器云、微服务、DevOps、数据治理、数字化转型等领域,对相关技术有独特的理解和见解。擅长于软件规划和设计,提出的“平台融合”的观点越来越得到认同和事实证明。发表了众多技术文章探讨容器平台建设、微服务技术、DevOps、数字化转型、数据治理、中台建设等内容,受到了广泛关注和肯定。
在DeepSeek 模型发布之前,对模型所使用的GPU卡精度运算能力没有太多关心,误以为不同的卡支持的计算精度类型是一样的,其实不同的GPU卡所支持的浮点精度类型可能差别很大,而且每种类型的卡对不同计算精度类型的算力支持也是不一样的。DeepSeek模型训练使用FP8精度,而当前众多的国产GPU卡都不支持FP8,所以只能转换为FP16精度运行,也因此对GPU资源的占用多了一倍。这也使我开始关注不同GPU卡对精度的支持问题。
认识到GPU卡的差异
对于不同的GPU卡来说,其软硬件架构、制程、工艺等不一样,也决定了其所集成的计算单元、存储、带宽等组件不一样的,而每种精度算力和其计算单元数量有关,因此,不同的卡可能对不同精度的支持和其算力的支持差别很大。例如英伟达卡每一次发布基本上都会带来架构和算力的更新、精度支持和算力的完善(下图内容未能深入研究,若有错误之处请批评指正)。如Tesla中加入了双精度FP64以支持科学和高性能计算(HPC),并在Fermi架构中改进了双精度FP64的性能。Hopper架构(如H100、H200、H20)能够支持FP8精度,就能以更节省的GPU卡资源完成模型训练。BlackWell架构推出了mini的小工作站,据说支持开发者对DeepSeek、Meta、Google等公司的最新一代推理AI模型进行原型制作、微调和推理,用的就是FP4精度。

对于国产GPU卡来说,在工艺、制程等方面还暂时无法跟英伟达媲美,在精度支持上也存在差距。国产GPU卡基本上大都不支持FP8精度,特别目前华为、海光、昆仑芯、阿里等的卡还都不支持(国产GPU卡有支持FP8精度的,感兴趣可自行搜索),如果要运行DeepSeek R1模型,就需要将FP8的权重文件转换为FP16格式或BF16格式,从而使显存的占用翻倍,也就是说资源占用和成本基本上是翻倍的,本来2台8卡的机器就可以运行的全参版本,现在需要4台8卡的机器才能运行,从而也可以看出计算精度对模型资源占用和成本的重要性。
GPU浮点数精度支持和适用场景
做过java或C++编程应该知道,浮点数用float和double数据类型表示,float占4个字节32位的存储空间,单精度,double占8个字节64位的存储空间,双精度。双精度比单精度表达的更精确,但是存储占用多一倍,计算耗时也更高,因此在满足精度要求的情况,可以尽可能减少存储空间和提升计算效率,也因此在模型AI模型训练等场景中出现了FP16、BF16半精度等类型。2022年9月由多家芯片厂商定义的FP8精度类型,2023年10月由香港科技大学等机构定义LLM-FP4精度,支持大语言模型Post-training等场景。FP8和FP4不是正式的浮点数类型,也提出的相对较晚,因此国内的算力卡大多都还不支持。
目前常用到的浮点数精度有双精度FP64、单精度(FT32、TF32、HF32)、半精度(FP16、BF16)、8位精度FP8(E4M3和E5M2两种格式),以及量化精度(INT8、INT4)和4位精度(FP4、NF4)等。不同精度所使用的场景也有差别。双精度FP64占用资源空间多,运行性能差,精度高,多用于高精度科学运算、金融建模、气候模拟等误差敏感场景。单精度FP32多用于复杂数学运算、图形渲染、深度学习推理等场景,占用显存等资源大。TF32是英伟达提出的面向深度学习训练的浮点数类型,它通过截短尾数大幅提升计算性能,在性能、范围和精度上实现了平衡。HF32是华为使用的模型训练浮点数类型,进一步减少尾数,更激进地牺牲精度换取速度,提升模型训练和推理性能。半精度(FP16、BF16)用于深度学习场景,训练友好,可处理梯度变化剧烈的问题等。BF16(Brain Float16),由Google Brain提出,也是为了机器学习而设计,由1个符号位,8位指数位(和FP32一致)和7位小数位(低于FP16)组成,其精度低于FP16,但是表示范围和FP32一致,和FP32之间很容易转换,用于大模型训练等。8位精度(FP8)是为大模型训练设计,如DeepSeekV3\R1等,极大减少了存储空间,进一步降低了对存储和算力需求。FP4是4位浮点量化精度,适合需要保留数值范围的应用如梯度量化;NF4是4位归一化浮点量化,适用于正态分布权重数据如大语言模型等。量化精度(INT8、INT4):适用于存储小、精度低场景,INT8适合推理阶段使用、推理高效,因此目前大部分DeepSeek R1模型部署量化 INT8版本,既基本达到模型效果,也大量节省资源和成本。INT4实现了极致压缩,但易失真,适合极端资源受限场景。
关于精度的基础介绍也非常多,有兴趣可以搜索深入学习。每种精度类型所适用的场景会有差别,因此不同的GPU或NPU卡由于生产时间、目的等不一样,因此适用的场景也有所区别。为了发挥卡的最佳性能,在运行时需要考虑业务模型等的场景。
在使用GPU卡进行模型训练和推理过程中,如果使用不正确,可能面临着一个浮点数精度损失的问题。
精度损失问题
精度损失本质源于数字在计算机中的表示方式与计算规则和现实数学逻辑的差异,浮点数二进制表示的固有缺陷所造成的。 十进制小数(如0.1、0.3)无法用有限位二进制小数精确表示,只能近似存储。例如 0.1的二进制表示为0.00011001100110011…(循环节为0011),计算机存储时需截断,导致初始舍入误差。这类误差在累加、迭代计算中会逐步累积,最终影响结果精度。另外浮点数存储位数的限制,单精度理论有效数字约7位十进制数,双精度有效数字约16位十进制数,因此,随着数字越来越大,数字的表示也越来越不精确。近似值的表示在进行计算时与真实值存在偏差。
第二是计算过程中的舍入误差累积造成的。在浮点数多步计算如迭代求解方程组、数值积分过程中,精度误差逐步传递累积,计算1e20 + 1 - 1e20时,因1e20与1的数量级差异极大,1在单精度下会被视为0,最终结果为0(真实值为1),另外当两个数量级差异超过指数位表示范围时,小数的尾数会被大数的尾数覆盖,也会造成大数“吞噬”小数现象。例如1000000000000 + 1在FP32中,因指数位限制,1的尾数无法被正确表示,结果仍为1000000000000。
第三是在数据类型转换过程中也会引发精度损失,如高精度向低精度转换,低精度类型的尾数位数不足,需截断高位有效数字。FP64数3.141592653589793转为FP32时,尾数位仅保留23位,结果变为3.1415927。整数与浮点数的转换也会造成误差,整数转浮点数:超大整数(如2^53 + 1)因超过FP64尾数表示范围,会被近似为2^53。浮点数转整数:小数部分直接舍弃(如3.999转整数为3)。
第四是算法设计与数值稳定性问题。在病态问题(Ill - conditioned Problem)处理中,输入的微小变化可能导致输出剧烈变化的计算问题。例:求解行列式接近零的线性方程组时,舍入误差会被放大,导致结果失真。或者错误的计算顺序也会导致误差产生。
第五是硬件架构与精度支持限制,低精度格式的固有缺陷易在复杂计算中积累误差。Tensor Core加速、混合精度训练都可能因精度转换中若未正确管理(如梯度缩放),可能导致梯度消失或爆炸,引发精度损失。
第六是特殊数值与边界条件处理,无穷大(Infinity)与非数(NaN),除以零、负数开平方等操作会生成NaN,后续计算中NaN会“污染”整个结果链;以及接近零的极小值(Subnormal Numbers),在计算中可能出现大量Subnormal数时,硬件可能切换至低效模式,导致精度与性能双重损失。
精度损失本质是离散化计算与连续数学模型之间的矛盾产物,其成因涵盖数字表示、计算规则、硬件架构和算法设计等多层级因素。在实际应用中,可通过选择合适的精度格式(如FP64替代FP32)、优化计算顺序、引入误差补偿算法(如Kahan求和)或采用混合精度训练策略,在计算效率与精度之间取得平衡。
模型精度需求和显卡匹配选型
由于不同的业务场景对精度的要求不一样,因此在实际GPU卡实践中,需要选择合适的GPU卡资源,有针对性地优化浮点数精度,以更好的匹配业务场景精度需求。不过当前实践中又往往受限于所拥有的GPU卡资源类型,以及数据安全、合规要求等,难以按需选择合适的GPU卡。不过深入理解精度对模型的影响,也能够更好的开发出更契合已有资源类型的模型。
浮点数精度优化可以从需求分析→算法设计→硬件选型→代码实现等构建精度优化的全生命周期管理流程,在实际应用中,应先通过误差分析定位主要损失源,再结合场景特性选择“精度格式+算法+硬件”的组合方案。例如在金融领域优先采用定点数与硬件校验,深度学习侧重混合精度与梯度管理,科学计算则依赖双精度算法与误差补偿。通过这种精准施策,可在保证业务精度要求的同时,最大化适配计算资源和资源利用率。
首先需要选择合适的精度格式,不同业务场景对精度要求不一样,根据业务场景精度要求,选择合适的精度,从而可以确定合适的GPU卡;其次,可以从算法层面尽可能抑制误差,通过优化计算顺序,同符号数有限相加以避免正负相消导致的损失,解决累加误差,顺序求和以防止大数吞噬小数等。第三可以利用GPU卡硬件和其架构特性,比如DeepSeek利用的P-D分离等,但这种方式需要对GPU的架构有深入的理解,而且可能不通用,难度比较大;第四可以在代码实现中显式控制精度转换等尽可能减少精度损失。总之,在使用GPU卡的实践中,为实现最大的算力利用,需要采用多种方式和手段,最基本的是选择合适的匹配的GPU卡。
来自 “ 汪照辉 ”, 原文作者:TWT ;原文链接:https://mp.weixin.qq.com/s/LWXrMMQskPI4rcATLJNzfQ,如有侵权,请联系管理员删除。