一文搞懂深度学习加速单元NPU的量化原理

本文详细探讨了深度学习中NPU的量化原理,包括量化带来的存储和计算效率提升,以及量化可能导致的精度损失。文章通过推导量化公式,解释了如何在NPU上进行量化计算,并通过实例验证了量化过程的准确性。量化过程的关键在于理解和处理量化参数,如Scale和Zero Point,以保持数据的无损转换。此外,文章还讨论了量化参数的确定和量化对模型部署的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

量化带来的好处有很多,首先,由于训练好的神经网络对数据精度以及噪声的不敏感,通过量化将参数从4byte float转换为1byte,从而减少了数据量,进而可以使用容量更小的存储设备,节省了成本;其次,量化带来计算效率的提升,单位时间,单位能效内的计算成果多了,或者说,同样的算力需求的模型,所消费的时间和能量少了,结果就是又快又省电,现在的移动终端都是用电池供电的,也就意味着更久的续航和更好的体验。经过量化的模型变小,这样也便于在线升级模型和算法,量化的好处很多很多,后面有时间再补充。 

量化虽好,但也不是没有缺点,首先是相对于float32,量化类型(int8/int16/uint8)的精度和动态范围要小很多,精度会掉,如下图:

再一个缺点就是量化操作实现复杂不好理解,尤其是结合复杂的网络拓扑结构之后,更是千头万绪难以把握,经过多日的思考,自感小有收获,权且记录在此,至于对错,我一直认为只要是自己下功夫思考得出的结论,正确推理无疑是第一位的,但错误反而更能促使我们对问题多角度的深入思考,敏锐我们的神经,下次再面对的时候,它将会保护我们不会被误导。很多时候,我们都是从错误中学习不是么?所以,以下内容,期待被打脸~

一个典型的神经网络拓扑结构如下,这是一个典型的全连接:

为了方便分析,将上图抽象一下,摘取和量化相关的主要部分,整理出来在NPU中运行时的模型为:

Q^{l-1}_o \ \ S^{l-1}_o \ \ Z^{l-1}_o:第l-1层输出量化值,Scale和Zero Point.

Q^{l}_i \ \ S^{l}_i \ \ Z^{l}_i:第l层输入量化值,Scale和Zero Point.并且:

Q^{l-1}_o==Q^{l}_i \ \ S^{l-1}_o == S^{l}_i \ \ Z^{l-1}_o==Z^{l}_i

Q^{l}_w \ \ S^{l}_w \ \ Z^{l}_w: 第l层权重量化值,Scale和Zero Point.

 Q^{l}_b \ \ S^{l}_b \ \ Z^{l}_b: 第l层偏置量化值,Scale和Zero Point.

Q^{l}_o \ \ S^{l}_o \ \ Z^{l}_o:第l层输出量化值,Scale和Zero Point.

Q^{l+1}_i \ \ S^{l+1}_i \ \ Z^{l+1}_i:第l+1层输入量化值,Scale和Zero Point.并且:

Q^{l}_o==Q^{l+1}_i \ \ S^{l}_o == S^{l+1}_i \ \ Z^{l}_o==Z^{l+1}_i

注意图中的S^{l+1}_i \ \ Z^{l+1}_i没有画出,通过这种输入和输出直接对接,不同层之间无缝连接再一起。

下面推导量化公式,看再NPU中,执行的运算是什么样子,下面的公式每个符号都表示矩阵或者向量,并非是scaler.

(Q^{l}_o - Z^{l}_o)S^l_o=(Q^l_i-Z^l_i)S^l_i \cdot (Q^l_w-Z^l_w)S^l_w +(Q^l_b-Z^l_b)S^l_b

所以:

(Q^{l}_o - Z^{l}_o)=(Q^l_i-Z^l_i)\cdot (Q^l_w-Z^l_w)\frac{S^l_i \cdot S^l_w}{S^l_o} +(Q^l_b-Z^l_b)\frac{S^l_b}{S^l_o}

所以:

\mathbf{Q^{l}_o=(Q^l_i-Z^l_i)\cdot (Q^l_w-Z^l_w)\frac{S^l_i \cdot S^l_w}{S^l_o} +(Q^l_b-Z^l_b)\frac{S^l_b}{S^l_o}+Z^{l}_o}

继续化简(其实是化繁,为了得到适合MAC计算的形式):                

Q^{l}_o=\frac{(Q^l_i-Z^l_i)\cdot (Q^l_w-Z^l_w)}{S^l_b}\frac{S^l_i \cdot S^l_w\cdot S^l_b}{S^l_o} +\frac{(Q^l_b-Z^l_b)}{S^l_i \cdot S^l_w}\frac{S^l_b\cdot S^l_i \cdot S^l_w}{S^l_o}+\frac{S^l_o }{S^l_i \cdot S^l_w\cdot S^l_b}Z^{l}_o

得到:               

\\ \boldsymbol{Q^{l}_o=\frac{(Q^l_i-Z^l_i)\cdot (Q^l_w-Z^l_w)}{S^l_b}\frac{S^l_i \cdot S^l_w\cdot S^l_b}{S^l_o} +\frac{(Q^l_b-Z^l_b)}{S^l_i \cdot S^l_w}\frac{S^l_b\cdot S^l_i \cdot S^l_w}{S^l_o}+\frac{ S^l_i \cdot S^l_w\cdot S^l_b }{S^l_o}\cdot \frac{S^l_o }{S^l_i \cdot S^l_w\cdot S^l_b}Z^{l}_o}

最终,得到公式:

### NCE Loss 的概念与实现 噪声对比估计(Noise Contrastive Estimation, NCE)是一种用于优化模型参数的方法,特别适用于处理大规模分类问题。它通过引入噪声分布来近似计算真实数据分布下的梯度,从而降低计算复杂度。 #### 噪声对比估计的核心思想 NCE 方法的目标是从大量候选类别中高效地估算目标类别的概率分布。其核心在于构建一个二元分类器,该分类器能够区分来自真实数据分布的样本和来自噪声分布的样本[^1]。具体来说,给定一个观测值 \(x\) 和对应的标签 \(y\),NCE 定义了一个新的目标函数: \[ L(\theta) = \sum_{i=1}^{n} \log p(y_i | x_i; \theta) \] 其中 \(p(y|x)\) 是基于 softmax 函数定义的概率分布。为了减少计算量,NCE 使用负采样的方式替代完整的 softmax 计算[^4]。 #### 数学表达式 假设真实的条件分布为 \(P_m(x|y)\),并设噪声分布为 \(Q(x)\),则可以定义一个新的联合分布 \(P'(x,y)\): \[ P'(x,y) = P(y)P_m(x|y) \] 以及相应的噪声分布: \[ Q'(x,y) = Q(x)Q(y) \] 最终,NCE 将问题转化为最大化以下对数似然函数: \[ \ell(\theta) = \mathbb{E}_{(x,y) \sim P'}[\log s_\theta(x,y)] + k \cdot \mathbb{E}_{(x', y') \sim Q'}[\log (1-s_\theta(x',y'))] \] 这里 \(s_\theta(x,y)\) 表示判别器输出的真实样本属于正类的概率,\(k\) 控制噪声样本的数量比例[^3]。 #### 实现代码示例 以下是 Python 中使用 TensorFlow 或 PyTorch 编写的一个简单 NCE 损失函数的例子: ```python import tensorflow as tf def nce_loss(inputs, labels, num_classes, embedding_size, num_sampled): weights = tf.Variable(tf.random.normal([num_classes, embedding_size])) biases = tf.Variable(tf.zeros([num_classes])) sampled_values = tf.nn.uniform_candidate_sampler( true_classes=tf.reshape(labels, [-1, 1]), num_true=1, num_sampled=num_sampled, unique=True, range_max=num_classes) loss = tf.reduce_mean( tf.nn.nce_loss(weights=weights, biases=biases, inputs=inputs, labels=labels, num_sampled=num_sampled, num_classes=num_classes)) return loss ``` 上述代码片段展示了如何利用 `tf.nn.nce_loss` 来简化 NCE 损失的计算过程。注意这里的 `num_sampled` 参数控制了从噪声分布中抽取多少个负样本。 #### 应用场景 NCE 广泛应用于自然语言处理领域中的词嵌入学习任务,比如 Word2Vec 模型。由于这些任务通常涉及非常大的词汇表大小,因此传统的 softmax 层会变得极其昂贵。相比之下,NCE 提供了一种高效的解决方案。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papaofdoudou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值