当前位置: 首页 > news >正文

【模型量化】量化基础

目录

一、认识量化

二、量化基础原理

2.1 对称量化和非对称量化

2.1.1 对称量化

2.1.2 非对称量化

2.1.3 量化后的矩阵乘

2.2 神经网络量化

2.2.1 动态量化

2.2.2 静态量化

2.3 量化感知训练


一、认识量化

量化的主要目的是节约显存、提高计算效率以及加快通信

deepseek-r1-7b 模型以不同数值类型加载随不同数据类型所占用的显存大小也完全不一样,int4 数值类型加载仅需 fp32 加载的 1/8 的显存。通过量化技术能够把模型里的浮点数参数转化为低精度的整数参数,以此实现参数压缩。这不但能够削减模型所需的存储空间,还能缩短模型加载耗时

FP32FP16INT8INT4
显存占用28G14G7G3.5G

量化就是把Float类型(FP32、FP16)的模型参数和激活值(分别对应参数量化、激活值量化),用整数(INT8、INT4)来代替

同时需要尽可能减少量化后模型推理的误差。可以来一些好处:

  1. 减少模型的存储空间和显存的占用
  2. 减少显存和Tensorcore之间的数据传输量,从而加快模型推理时间
  3. 显卡对整数运算速度快于浮点型数据。从而加快模型推理时间

二、量化基础原理

量化就是使 x_{f} \rightarrow x_{q}(量化)、x_{q} \rightarrow x_{f^{'}}(反量化),同时 x_{f} 和 x_{f^{'}} 要尽可能的接近

2.1 对称量化和非对称量化

2.1.1 对称量化

对称量化的原理就是找到 x_{f} 中绝对值的最大值,然后对其进行缩放得到量化后的值,然后进行反量化得到原来的值,可以看出量化是存在一定误差的

这样量化的缺点就是,可能会有数值映射空间被浪费( x_{f} 中最大值对应映射空间的最大值,但最小值不对应映射空间最小值。如上图,最小值为-92,-93 ~ -127这段空间被浪费)。为了让量化后的数值空间被充分利用,引入非对称量化

2.1.2 非对称量化

非对称量化有一个额外的参数Z调整零点的映射,这个参数通常称为零点。非对称量化表示的范围没有严格的限制,可以根据浮点值的范围,选取任意的想要表示的范围。因此非对称量化的效果通常比对称量化好,但需额外存储以及推理时计算零点相关的内容

对称量化具有计算简单,精度低等特点,非对称量化的计算有一个额外的参数Z调整零点的映射,因此计算复杂,但精度相对较高

2.1.3 量化后的矩阵乘

下图为对称量化在居中乘法当中的应用示意图(非对称量化也类似),通过量化,将浮点矩阵的乘法,转化为整数矩阵的乘法,虽然存在一定误差,但误差不大。在矩阵乘法中采用量化可以降低计算复杂度,提升矩阵乘法效率

N * N 的矩阵,量化前共有 N^{2} 次浮点数计算,量化后有 N^{2} 次整型计算、N次浮点数与整型计算、一次浮点数计算。看似计算次数增多,整型数据在计算速度与传输速度上都大于浮点数

2.2 神经网络量化

为什么量化不会损失太多精度?

  1. 因为一般权重和输入都经过 Normalization,基本数值范围都不大
  2. 激活函数,数值影响会被平滑
  3. 对于绝大部分分类神经网络,最后都是概率值,只要最后某种类别概率高于其他类别就可以,不需要绝对数值准确

量化在神经网络中的是对每一层而言,每一层进行量化计算,每一层输出时进行反量化。具体而言,量化在神经网络中的应用又可分为动态量化(Post Training Quantization Dynamic, PTQ Dynamic)与静态量化(Post Training Quantization Static, PTQ Static)

2.2.1 动态量化

在模型推理过程中动态计算量化参数,仅量化权重,激活值在推理时动态量化。通常适用于Transformer、RNN、LSTM等

  • 仅对权重(Weights)进行量化,激活保持 FP32
  • 不需要标定数据

量化流程

  1. 将训练好的模型权重量化为INT8,并保存量化参数
  2. 在模型推理时,对每一层输入的FP32激活值,动态进行进行量化为INT8
  3. 在每一层对量化后的INT8权重和INT8激活值进行计算
  4. 在每一层输出时将结果反量化为FP32
  5. 将FP32激活值传入到下一层

直接使用 torch.quantization.quantize_dynamic() 来实现量化操作即可,量化需要在CPU中完成,所以需要把设备信息设置为CPU

import torch
import torch.nn as nnclass Model(nn.Module):def __init__(self):super(Model, self).__init__()self.linear1 = nn.Linear(768, 512)self.linear2 = nn.Linear(512, 314)self.linear3 = nn.Linear(314, 128)self.linear4 = nn.Linear(128, 64)self.relu = nn.ReLU()self.sigmoid = nn.Sigmoid()def forward(self, data):data = self.linear1(data)data = self.relu(data)data = self.linear2(data)data = self.relu(data)data = self.linear3(data)data = self.relu(data)data = self.linear4(data)data = self.sigmoid(data)return datadef main():torch.manual_seed(100)data = torch.randn(4, 768)# 量化前推理model = Model()output1 = model(data)print(output1)# 量化模型quantized_model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)# 量化后推理output2 = quantized_model(data)print(output2)# 模型保存torch.save(model, "./model")torch.save(quantized_model, "./quantized_model")if __name__ == "__main__":main()

调用 PyTorch 的 quantize_dynamic 函数对模型进行动态量化。指定量化 torch.nn.Linear 类型的层,将权重量化为 torch.qint8 类型,得到量化后的模型 quantized_model

模型中的所有 Linear 层变成了 DynamicQuantizedLinear 层

量化前后的模型输出会有一定差异,在实际使用中需要进行评估

tensor([[0.5179, 0.5051, 0.4849, 0.5051, 0.4962, 0.5127, 0.4963, 0.5223, 0.4858,0.5173, 0.4973, 0.4957, 0.4949, 0.4768, 0.5024, 0.4924, 0.4922, 0.5089,0.4982, 0.5187, 0.5301, 0.5003, 0.4945, 0.4974, 0.5036, 0.4974, 0.4658,0.4953, 0.5032, 0.5247, 0.4908, 0.5290, 0.4965, 0.5145, 0.4883, 0.5193,0.4864, 0.4947, 0.4970, 0.5083, 0.5006, 0.4734, 0.5016, 0.4797, 0.5154,0.5057, 0.5040, 0.4682, 0.5352, 0.5256, 0.4836, 0.5180, 0.4835, 0.4852,0.4819, 0.4781, 0.5027, 0.5042, 0.5164, 0.4814, 0.4754, 0.5106, 0.4996,0.5029],[0.5113, 0.5056, 0.4846, 0.5065, 0.4973, 0.4976, 0.4927, 0.5228, 0.4896,0.5117, 0.4979, 0.5049, 0.4964, 0.4696, 0.5109, 0.4985, 0.5010, 0.5215,0.5086, 0.5067, 0.5211, 0.5040, 0.4869, 0.4992, 0.5084, 0.5005, 0.4787,0.4884, 0.5010, 0.5216, 0.4869, 0.5285, 0.5032, 0.5114, 0.4842, 0.5166,0.4952, 0.4936, 0.5116, 0.5120, 0.4992, 0.4769, 0.5055, 0.4885, 0.5158,0.5016, 0.5039, 0.4801, 0.5199, 0.5355, 0.4835, 0.5116, 0.4831, 0.4764,0.4839, 0.4875, 0.5008, 0.4939, 0.5186, 0.4934, 0.4857, 0.5133, 0.5041,0.5088],[0.5060, 0.4920, 0.4859, 0.5196, 0.4865, 0.4944, 0.4927, 0.5032, 0.4783,0.5114, 0.5037, 0.5060, 0.5006, 0.4747, 0.4914, 0.4853, 0.4866, 0.5140,0.5123, 0.5206, 0.5369, 0.4999, 0.5022, 0.4968, 0.5095, 0.4960, 0.4667,0.4771, 0.4929, 0.5121, 0.4905, 0.5138, 0.5042, 0.5163, 0.4904, 0.5030,0.4818, 0.4835, 0.4928, 0.5165, 0.5134, 0.4696, 0.4991, 0.4817, 0.5264,0.5011, 0.4912, 0.4741, 0.5414, 0.5255, 0.4847, 0.5115, 0.4963, 0.4668,0.4893, 0.4925, 0.4882, 0.5030, 0.5091, 0.4816, 0.4877, 0.5033, 0.4960,0.5164],[0.5186, 0.4994, 0.4805, 0.5198, 0.4900, 0.4988, 0.4904, 0.5132, 0.4820,0.5176, 0.5004, 0.5027, 0.4984, 0.4646, 0.5005, 0.4931, 0.4922, 0.5190,0.5077, 0.5191, 0.5297, 0.5008, 0.4907, 0.4966, 0.5053, 0.5080, 0.4790,0.4849, 0.5159, 0.5269, 0.4804, 0.5240, 0.5023, 0.5079, 0.4939, 0.5178,0.4892, 0.4996, 0.5001, 0.5066, 0.4999, 0.4768, 0.4974, 0.4833, 0.5160,0.5086, 0.5015, 0.4754, 0.5317, 0.5420, 0.4927, 0.5129, 0.4932, 0.4706,0.4743, 0.4742, 0.4948, 0.5074, 0.5127, 0.4840, 0.4751, 0.5050, 0.4937,0.5095]], grad_fn=<SigmoidBackward0>)
tensor([[0.5185, 0.5053, 0.4851, 0.5046, 0.4961, 0.5130, 0.4963, 0.5226, 0.4856,0.5172, 0.4971, 0.4955, 0.4947, 0.4766, 0.5030, 0.4925, 0.4923, 0.5091,0.4986, 0.5187, 0.5297, 0.5004, 0.4943, 0.4972, 0.5033, 0.4974, 0.4658,0.4953, 0.5032, 0.5246, 0.4906, 0.5291, 0.4970, 0.5148, 0.4879, 0.5194,0.4863, 0.4949, 0.4967, 0.5085, 0.5010, 0.4734, 0.5017, 0.4797, 0.5159,0.5061, 0.5044, 0.4683, 0.5351, 0.5254, 0.4838, 0.5180, 0.4838, 0.4853,0.4821, 0.4779, 0.5027, 0.5046, 0.5162, 0.4814, 0.4750, 0.5106, 0.4993,0.5028],[0.5117, 0.5056, 0.4841, 0.5065, 0.4975, 0.4975, 0.4928, 0.5230, 0.4897,0.5118, 0.4982, 0.5047, 0.4963, 0.4697, 0.5111, 0.4988, 0.5008, 0.5218,0.5085, 0.5063, 0.5207, 0.5040, 0.4865, 0.4991, 0.5083, 0.5008, 0.4787,0.4887, 0.5011, 0.5217, 0.4867, 0.5284, 0.5036, 0.5114, 0.4844, 0.5164,0.4954, 0.4937, 0.5115, 0.5119, 0.4991, 0.4770, 0.5053, 0.4886, 0.5156,0.5018, 0.5041, 0.4802, 0.5199, 0.5357, 0.4837, 0.5113, 0.4827, 0.4762,0.4834, 0.4870, 0.5011, 0.4941, 0.5187, 0.4936, 0.4859, 0.5132, 0.5039,0.5088],[0.5062, 0.4918, 0.4858, 0.5190, 0.4866, 0.4945, 0.4927, 0.5030, 0.4787,0.5113, 0.5031, 0.5057, 0.5007, 0.4748, 0.4913, 0.4854, 0.4867, 0.5144,0.5122, 0.5206, 0.5371, 0.5000, 0.5022, 0.4967, 0.5097, 0.4959, 0.4666,0.4771, 0.4929, 0.5123, 0.4904, 0.5138, 0.5046, 0.5163, 0.4904, 0.5028,0.4816, 0.4833, 0.4927, 0.5167, 0.5137, 0.4695, 0.4992, 0.4816, 0.5264,0.5014, 0.4912, 0.4741, 0.5411, 0.5254, 0.4851, 0.5116, 0.4962, 0.4667,0.4894, 0.4923, 0.4883, 0.5032, 0.5092, 0.4813, 0.4878, 0.5030, 0.4961,0.5168],[0.5190, 0.4993, 0.4803, 0.5200, 0.4900, 0.4990, 0.4905, 0.5135, 0.4821,0.5172, 0.5004, 0.5026, 0.4980, 0.4645, 0.5009, 0.4930, 0.4923, 0.5193,0.5079, 0.5190, 0.5296, 0.5006, 0.4906, 0.4968, 0.5051, 0.5082, 0.4793,0.4848, 0.5156, 0.5268, 0.4804, 0.5241, 0.5025, 0.5077, 0.4939, 0.5179,0.4895, 0.4997, 0.5000, 0.5068, 0.5001, 0.4765, 0.4975, 0.4836, 0.5158,0.5087, 0.5017, 0.4753, 0.5316, 0.5416, 0.4925, 0.5126, 0.4932, 0.4707,0.4744, 0.4743, 0.4948, 0.5075, 0.5128, 0.4840, 0.4749, 0.5050, 0.4938,0.5095]])

完成动态量化后,模型的大小会得到缩小

训练后动态量化存在的问题:

  1. 每次推理时每层都要对输入统计量化参数(如:比例因子和零点),耗时
  2. 每层计算完都转化为FP32,存入显存,占用显存带宽

2.2.2 静态量化

  • 针对动态量化的问题1:通过用有代表性的输入数据跑一遍整个网络,通过统计得到每层大概得量化参数来解决
  • 问题2:这一层的输出是下一层的输入。下一层还是要量化,通过在这一层直接量化好再传给下一层方法来解决

静态量化流程如下:

  1. 将训练好的模型权重量化为INT8,并保存量化参数
  2. 校准(calibration):利用一些有代表性的数据进行模型推理,用这些数据在神经网络每一层产生的激活估算出激活值的量化参数。这样就不用推理时每次根据实际激活值计算量化参数
  3. 在每一层对量化后的INT8权重和INT8激活值进行计算
  4. 在每一层输出时将结果反量化为FP32,同时根据校准产生的激活值量化参数,把激活值量化为INT8,把量化参数放入量化后的激活值中
  5. 将INT8的激活值和其量化参数传入到下一层

反量化+量化:反量化时用的是上一层的量化参数,量化时用的是本层的量化参数

具体实现

import torch
import torch.nn as nn
import torch.ao.quantization as quantizationclass Model(nn.Module):def __init__(self):super(Model, self).__init__()self.quant = quantization.QuantStub()self.dequant = quantization.DeQuantStub()self.linear1 = nn.Linear(768, 512)self.linear2 = nn.Linear(512, 314)self.linear3 = nn.Linear(314, 128)self.linear4 = nn.Linear(128, 64)self.relu = nn.ReLU()self.sigmoid = nn.Sigmoid()def forward(self, data):data = self.quant(data)data = self.linear1(data)data = self.linear2(data)data = self.dequant(data)data = self.relu(data)data = self.quant(data)data = self.linear3(data)data = self.dequant(data)data = self.relu(data)data = self.quant(data)data = self.linear4(data)data = self.dequant(data)data = self.sigmoid(data)return datadef main():torch.manual_seed(100)data = torch.randn(2, 768)# 量化前推理model = Model()output1 = model(data)print(output1)# 量化模型weight_observer = quantization.PerChannelMinMaxObserver.with_args(dtype=torch.qint8, qscheme=torch.per_channel_symmetric, quant_min=-128, quant_max=127)activation_observer = quantization.MinMaxObserver.with_args(dtype=torch.quint8, qscheme=torch.per_tensor_affine, quant_min=0, quant_max=255)qconfig = quantization.QConfig(activation=activation_observer,weight=weight_observer)model.qconfig = qconfigmodel_prepared = quantization.prepare(model)model_prepared(data)model_int8 = quantization.convert(model_prepared)# 量化后推理output2 = model_int8(data)print(output2)# 查看模型print(model)print(model_int8)print("int8 model linear1 parameter (int8):\n", torch.int_repr(model_int8.linear1.weight()))print("int8 model linear1 parameter:\n", model_int8.linear1.weight())# 模型保存torch.save(model, "./model")torch.save(model_int8, "./model_int8")if __name__ == "__main__":main()

量化有多个 qscheme,可以根据具体情况进行控制

2.3 量化感知训练

量化会存在误差。量化感知训练就是在网络训练过程中,模拟量化,让模型在训练过程中就能调整参数,让其更适合量化,提高量化后模型的精度

  1. 加载FP32的模型参数
  2. 输入FP32的激活值
  3. 通过在网络里插入模拟量化节点(fake_quantization)来分别对模型参数和激活值进行量化和反量化。从而引入量化误差
  4. 模型在FP32精度下进行计算
  5. 计算后的激活值传入下一层

import torch
import torch.nn as nn
import torch.ao.quantization as quantizationtorch.manual_seed(123)class Model(nn.Module):def __init__(self):super(Model, self).__init__()self.quant = quantization.QuantStub()self.dequant = quantization.DeQuantStub()self.linear1 = nn.Linear(768, 512)self.linear2 = nn.Linear(512, 314)self.linear3 = nn.Linear(314, 128)self.linear4 = nn.Linear(128, 64)self.relu = nn.ReLU()self.sigmoid = nn.Sigmoid()def forward(self, data):data = self.quant(data)data = self.linear1(data)data = self.linear2(data)data = self.dequant(data)data = self.relu(data)data = self.quant(data)data = self.linear3(data)data = self.dequant(data)data = self.relu(data)data = self.quant(data)data = self.linear4(data)data = self.dequant(data)data = self.sigmoid(data)return datadef main():torch.manual_seed(123)train_data = torch.randn(30000, 768)torch.manual_seed(123)train_label = torch.randn(30000, 64)model = Model()weight_observer = quantization.PerChannelMinMaxObserver.with_args(dtype=torch.qint8, qscheme=torch.per_channel_symmetric, quant_min=-128, quant_max=127)activation_observer = quantization.MinMaxObserver.with_args(dtype=torch.quint8, qscheme=torch.per_tensor_affine, quant_min=0, quant_max=255)qconfig = quantization.QConfig(activation=activation_observer,weight=weight_observer)model.qconfig = qconfigmodel_prepared = quantization.prepare_qat(model)optimizer = torch.optim.Adam(model_prepared.parameters(), lr=0.01)for i in range(10):preds = model_prepared(train_data)loss = torch.nn.functional.mse_loss(preds, train_label)loss.backward()optimizer.step()optimizer.zero_grad()print("loss:", i, loss)if __name__ == "__main__":main()

直接将准备量化感知训练模型 model_prepared = torch.ao.quantization.prepare_qat(model),将量化参数视为可训练的,以此来降低损失

相关文章:

【模型量化】量化基础

目录 一、认识量化 二、量化基础原理 2.1 对称量化和非对称量化 2.1.1 对称量化 2.1.2 非对称量化 2.1.3 量化后的矩阵乘 2.2 神经网络量化 2.2.1 动态量化 2.2.2 静态量化 2.3 量化感知训练 一、认识量化 量化的主要目的是节约显存、提高计算效率以及加快通信 dee…...

智能 + 安全:婴幼儿托育管理实训基地标准化建设方案

婴幼儿托育服务与管理实训基地智能安全的开发&#xff0c;需以“岗位能力-职业标准-行业需求”为核心逻辑&#xff0c;构建“需求分析-课程设计-教学实施-效果评估”全闭环体系。结合托育行业难点、技术赋能手段及职业能力要求&#xff0c;呈现课程开发全流程&#xff0c;重点突…...

AI重构家居营销新范式:DeepSeek如何破解行业流量与转化困局?

1. 流量下滑、成本攀升、内容同质化&#xff1a;家居行业亟需一场“效率革命” 中国家居行业正经历一场深刻的转型阵痛。线下门店客流量持续萎缩&#xff0c;线上获客成本攀升至临界点&#xff0c;传统营销模式陷入“高投入、低转化”的泥潭&#xff1b;智能家居产品快速迭代&…...

机器学习实操 第一部分 机器学习基础 第7章 集成学习与随机森林

机器学习实操 第一部分 机器学习基础 第7章 集成学习与随机森林 内容概要 第7章深入探讨了集成学习方法&#xff0c;这是一种结合多个预测模型&#xff08;如分类器或回归器&#xff09;以提高预测性能的技术。这些方法通过利用群体的智慧&#xff0c;可以比单个模型获得更好…...

如何用GPU Instancing来优化树木草石重复模型

1&#xff09;如何用GPU Instancing来优化树木草石重复模型 2&#xff09;Unity ASTC压缩后的纹理在部分安卓机型上不显示 3&#xff09;现在大部分项目的竖版UI设计分辨率是多少 4&#xff09;Android上拖拽物体不实时跟随手指的问题 这是第430篇UWA技术知识分享的推送&#x…...

Windows服务器部署全攻略:Flask+Vue+MySQL跨平台项目实战(pymysql版)

当你的后端(Flask+pymysql,Windows开发)与前端(Vue,Mac开发)需要统一部署到Windows服务器时,通过「IIS反向代理+原生组件适配」方案可实现稳定交互。以下是针对Windows环境的专属部署指南,解决路径适配、服务启动等核心问题。 一、Windows服务器环境准备(必做!) 1…...

自动驾驶-一位从业两年的独特视角

时间简介 2023.03 作为一名大三学生&#xff0c;加入到某量产车企&#xff0c;从事地图匹配研发 2023.07 地图匹配项目交付&#xff0c;参与离线云端建图研发 2023.10 拿到24届校招offer 2024.07 正式入职 2025.01 离线云端建图稳定&#xff0c;开始接触在线车端融图研发 自动…...

Vue 3 单文件组件中 VCA 语法糖及核心特性详解

在 Vue.js 的开发世界里&#xff0c;单文件组件&#xff08;Single File Components&#xff0c;简称 SFC&#xff09;是构建复杂应用的基石。它将 HTML、CSS 和 JavaScript 代码封装在一个.vue文件中&#xff0c;极大地提高了代码的可维护性和复用性。 本文将深入探讨单文件组…...

iVX:数字化转型全场景技术革新与生态构建实践

在数字经济蓬勃发展的当下&#xff0c;企业数字化转型需求日益迫切。iVX 凭借其独特的技术架构与创新解决方案&#xff0c;深度渗透工业互联网、元宇宙、智慧城市等领域&#xff0c;成为推动全场景数字化转型的重要力量。本文将重新梳理 iVX 的技术应用与生态价值&#xff0c;以…...

车辆检测新突破:VFM-Det 如何用大模型提升识别精度

目录 ​编辑 一、摘要 二、引言 三、相关工作 四、Coovally AI模型训练与应用平台 五、方法 概述 综述&#xff1a;基于区域建议的检测 基于VehicleMAE的感知器 六、实验分析 数据集与评估指标 实现细节 属性预测模块预训练 与SOTA检测器的对比实验 消融实验 V…...

可视化图解算法:判断是否完全二叉树

1. 题目 描述 给定一个二叉树&#xff0c;确定他是否是一个完全二叉树。 完全二叉树的定义&#xff1a;若二叉树的深度为 h&#xff0c;除第 h 层外&#xff0c;其它各层的结点数都达到最大个数&#xff0c;第 h 层所有的叶子结点都连续集中在最左边&#xff0c;这就是完全二…...

对于C++中的STL,push_back()和emplace_back()有什么区别?

1.push_back()&#xff1a; 语法为&#xff1a;container.push_back()&#xff0c;接收一个值或一个对象的移动/复制副本&#xff1b; 在将对象添加或移动到容器的末尾前&#xff0c;需要先调用构造函数实例化对象&#xff0c;然后再执行移动或复制操作。 2.emplace_back()&a…...

小程序中的页面跳转

小程序中的页面跳转 在之前网页的学习中&#xff0c;我们往往采用超链接&#xff0c;或者定义方法、函数等方式来实现页面的跳转&#xff0c;但是微信小程序中没有超链接&#xff0c;那我们该如何实现呢&#xff1f;微信小程序的页面跳转包括两个&#xff0c;一个是tabBar页面…...

分享一款免费的AI IDE Trae,全新支持DeepSeek R1/V3、豆包大模型1.5自由切换,更可自定义专属AI模型

分享一款免费的AI IDE Trae&#xff0c;全新支持DeepSeek R1/V3、豆包大模型1.5自由切换,更可自定义专属AI模型,加入我的邀请一起拿好礼,转发给技术搭子还有机会赢取华为MatePad Air、雷蛇机械键盘、热门会员卡等丰厚奖品&#xff0c;即刻体验>>: https://juejin.cn/loy…...

美团优选小程序 mtgsig 分析 mtgsig1.2

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 部分python代码 openId a…...

Java中的多态与继承

Java中的多态与继承 开始学习Java中的多态及如何在多态方法调用中进行方法调用 多态——即对象根据其类型执行特定操作的能力——是Java代码灵活性的核心。四人组&#xff08;Gang Of Four&#xff09;创建的许多设计模式都依赖于某种形式的多态&#xff0c;包括命令模式。本文…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(12): ておき ます

日语学习-日语知识点小记-构建基础-JLPT-N4阶段&#xff08;12&#xff09;&#xff1a; ておき ます。 1、前言&#xff08;1&#xff09;情况说明&#xff08;2&#xff09;工程师的信仰 2、知识点&#xff08;1&#xff09;&#xff5e;ておき ます。&#xff08;2&#x…...

MicroPython for esp32s3开发HX711称重模块指南

一、HX711模块基本介绍 一&#xff09;、核心功能 ‌24位高精度ADC‌ 专为称重传感器设计的模数转换芯片&#xff0c;支持20mV或40mV满幅差分输入内置128/64倍可编程增益放大器&#xff08;通道A&#xff09;及固定32倍增益&#xff08;通道B&#xff09; ‌集成化设计‌ 集成…...

智能机器人在物流行业的应用:效率提升与未来展望

随着全球电子商务的蓬勃发展&#xff0c;物流行业正面临着前所未有的挑战和机遇。传统的物流模式已经难以满足日益增长的市场需求&#xff0c;尤其是在效率、成本控制和精准配送方面。智能机器人技术的出现&#xff0c;为物流行业的转型升级提供了强大的动力。本文将探讨智能机…...

MiWi|Microchip开发的专有无线通信协议,适用于低功耗、短距离的无线个人局域网【无线通信小百科】

1、什么是MiWi MiWi&#xff08;Microchip Wireless&#xff09;是一种由 Microchip 公司开发的专有无线通信协议。 它基于 IEEE 802.15.4 标准&#xff0c;适用于低功耗、短距离的无线个人局域网&#xff08;WPAN&#xff0c;Wireless Personal Area Network&#xff09;。 M…...

分布式事务,事务失效,TC事务协调者

1. 概述 本方案书旨在解决分布式系统中事务一致性问题&#xff0c;重点阐述全局事务标识&#xff08;XID&#xff09;的传递与存储机制、事务协调者&#xff08;TC&#xff09;的设计与部署&#xff0c;以及分布式事务失效场景的应对策略。基于业界成熟框架&#xff08;如Seat…...

ESP32开发-作为TCP客户端发送数据到网络调试助手

​​代码&#xff08;作为TCP客户端&#xff09;​​ #include <SPI.h> #include <EthernetENC.h> // 使用EthernetENC库// 网络配置 byte mac[] {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // MAC地址 IPAddress ip(192, 168, 1, 100); // ESP32的IP IPAddr…...

halcon打开图形窗口

1、dev_open_window 参数如下&#xff1a; 1&#xff09;Row(输入参数) y方向上&#xff0c;图形窗口距离左上角顶端的像素个数 2&#xff09;Column(输入参数) x方向上&#xff0c;距离左上角左边的像素个数 3&#xff09;Width(输入参数) 图形窗口宽度 4&#xff09;He…...

LVGL -按键介绍 下

4 图标 4.1 内置图标 LVGL 提供了一个很方便的 图标字体 系统&#xff0c;它使用了 lv_label 来显示文本或图标。你可以选择 Font Awesome 或其他图标字体&#xff0c;并将其直接嵌入应用中。LVGL 内建图标字体&#xff08;如 LV_SYMBOL_*&#xff09;是可以改变大小的。通过…...

【默子速报】DeepSeek新模型 Prover-V2 报告解读

炸裂&#xff0c;太炸裂了&#xff0c;五一不放假是吧&#xff1f;&#xff01; 默子加班加点的肝解读&#xff01; 首先是&#xff0c;Deepseek今天下午显示毫无预兆的在HF上发布了最新的Prover-V2参数 直接让一群人瞬间热血沸腾&#xff0c;想要看看Deepseek又干了什么大事。…...

冰冰一号教程网--介绍采用vuepress搭建个人博客

文章说明 采用vuepress可以快速搭建个人网站&#xff0c;风格统一&#xff1b;采用GPT可以将博文转化为个人博客网站 冰冰一号教程网 访问地址 目前只支持到 2025年05月1号 22点 教程包括主流编程语言&#xff1a;Java、JavaScript、python、C语言、C、C# 教程讲义由GPT生成&am…...

借助电商 API 接口实现电商平台商品数据分析的详细步骤分享

在数字化商业浪潮中&#xff0c;电商平台积累了海量数据。如何从这些数据中挖掘有价值的信息&#xff0c;成为电商企业提升竞争力的关键。电商 API 接口在这一过程中发挥着核心作用&#xff0c;它为获取和分析商品数据提供了高效途径。本文将详细介绍借助电商 API 接口实现电商…...

32单片机——串口

1、通信 通信的方式可以分为多种&#xff1a; &#xff08;1&#xff09;按照数据传送方式可分为串行通信和并行通信&#xff1b; ①串行通信 基本特征&#xff1a;数据逐位顺序依次传输 优点&#xff1a;传输线少、布线成本低、灵活度高等优点&#xff0c;一般用于近距离人…...

6.应用层

6. 应用层 1. 概述 应用层是计算机网络体系结构的最顶层&#xff0c;是设计和建立计算机网络的最终目的&#xff0c;也是计算机网络中发展最快的部分 早期基于文本的应用&#xff08;电子邮件、远程登录、文件传输、新闻组&#xff09;20世纪90年代将因特网带入千家万户的万维…...

【鸿蒙HarmonyOS】一文详解华为的服务卡片

7.服务卡片 1.什么是卡片 Form Kit&#xff08;卡片开发服务&#xff09;提供一种界面展示形式&#xff0c;可以将应用的重要信息或操作前置到服务卡片&#xff08;以下简称“卡片”&#xff09;&#xff0c;以达到服务直达、减少跳转层级的体验效果。卡片常用于嵌入到其他应…...

深度卷积模型:案例研究

1 为什么要进行案例研究&#xff1f; 过去&#xff0c;计算机视觉中的大量研究都集中在如何将卷积层、池化层以及全连接层这些基本组件组合起来&#xff0c;形成有效的卷积神经网络。 找感觉的最好方法之一就是去看一些示例&#xff0c;就像很多人通过看别人的代码来学习编程一…...

BBR 的 RTT 公平性问题求解

如果 BBR 要跟 reno/cubic 公平&#xff0c;只能顾此失彼&#xff0c;没有任何变通方法&#xff0c;唯一的方法就是在放弃 reno/cubic&#xff0c;但前提你得保证 BBR 流之间是公平的。如果非要照顾 reno/cubic&#xff0c;那就必须要变成 reno/cubic&#xff0c;这就是 BBRv2/…...

SQL命令二:SQL 高级查询与特殊算法

引言 在掌握了 SQL 的基础操作和建表约束后&#xff0c;我们可以进一步探索 SQL 的高级查询功能和一些特殊算法。这些高级技巧能够帮助我们更高效地处理和分析数据&#xff0c;满足复杂的业务需求。 一、查询进阶 &#xff08;一&#xff09;简单查询 简单查询通过 select 语…...

Databend 产品月报(2025年4月)

很高兴为您带来 Databend 2025 年 4 月的最新更新、新功能和改进&#xff01;我们希望这些增强功能对您有所帮助&#xff0c;并期待您的反馈。 BendDeploy&#xff1a;安装 Databend 的新方式 BendDeploy 是由 Databend 开发的一款基于 Kubernetes 的平台&#xff0c;旨在简化…...

Best Video下载器——全能高清无水印视频下载工具

在当今短视频和流媒体盛行的时代&#xff0c;用户经常遇到想要下载视频却受限于平台限制的情况。无论是收藏喜欢的影视片段、保存有价值的教程&#xff0c;还是进行二次创作&#xff0c;一款高效、免费且支持多平台的视频下载工具显得尤为重要。Best Video下载器正是为此而生&a…...

2025东三省D题深圳杯D题数学建模挑战赛数模思路代码文章教学

完整内容请看文章最下面的推广群 一、问题一&#xff1a;混合STR图谱中贡献者人数判定 问题解析 给定混合STR图谱&#xff0c;识别其中的真实贡献者人数是后续基因型分离与个体识别的前提。图谱中每个位点最多应出现2n个峰&#xff08;n为人数&#xff09;&#xff0c;但由…...

这些是什么充电模块调试手段,对USB、Thermal、DP

在电子产品开发中&#xff0c;充电模块调试及对相关模块的了解是保障产品性能与稳定性的关键环节。下面为你详细介绍&#xff1a; 充电模块调试手段&#xff1a;充电模块负责将外部电源的电能转化为适用于设备的电能&#xff0c;并对电池进行充电管理。调试手段包括使用专业的…...

Gradio全解20——Streaming:流式传输的多媒体应用(2)——构建对话式聊天机器人

Gradio全解20——Streaming&#xff1a;流式传输的多媒体应用&#xff08;2&#xff09;——构建对话式聊天机器人 本篇摘要20. Streaming&#xff1a;流式传输的多媒体应用20.2 构建对话式聊天机器人20.2.1 应用概述20.2.2 记录用户音频20.2.3 存储音频并生成响应20.2.4 构建G…...

字节暑期实习-网络运维工程师面经

岗位描述 这个是ByteIntern实习&#xff0c;是暑期实习岗位 岗位 一面 先自我介绍 抓项目技术&#xff08;会进行确认是什么技术&#xff09; TCP的三次握手和四次挥手 序列号和确认应答号的位置和大小 序列号是随机的吗&#xff1f; 序列号为什么是随机的&#xff1f; …...

多用户远程 Debugger 服务隔离方案技术实践

多用户远程 Debugger 服务隔离方案技术实践 摘要&#xff1a; 针对多用户同时连接远程 Debugger 服务可能导致的断点冲突、调试流程干扰等问题&#xff0c;本文基于主流调试工具&#xff08;如 Python debugpy、Java JDWP、Node.js Inspector 等&#xff09;&#xff0c;梳理和…...

华为发布全球首个L3商用智驾ADS4.0

2024年10月2024世界智能网联汽车大会上&#xff0c;余承东讲到&#xff1a;“华为ADS 4.0将于2025年推出高速L3级自动驾驶商用及城区L3级自动驾驶试点&#xff0c;希望加快L3级自动驾驶标准的进程&#xff0c;推动L3级自动驾驶技术的普及。” 世界智能网联汽车大会演讲PPT 所以…...

Silo 科学数据工具库安装与使用指南

Silo 科学数据工具库安装与使用指南 Silo 是一个用于科学数据可视化和分析的工具库&#xff0c;由 Lawrence Livermore National Laboratory (LLNL) 开发。以下是 Silo 的安装和使用方法&#xff1a; 安装 Silo Linux 系统安装 从源码安装&#xff1a; wget https://wci.lln…...

vs2019编译occ7.9.0时,出现fatal error C1060: compiler is out of heap space

问题描述 visual studio 2019编译opencascade 7.9.0时&#xff0c;出现编译错误 fatal error C1060: compiler is out of heap space 解决方案 修改vs2019并行编译的线程个数&#xff0c;默认是12个&#xff0c;我改成了4个&#xff0c;问题解决 Tools > Project and Sol…...

Poco C++全面开发指南:网络应用开发

UDP接收器 项目结构 poco_demo/ ├── CMakeLists.txt ├── src/ │ ├── main.cpp │ └── Receiver.cpp └── include/└── Receiver.h创建 Receiver.h #pragma once#include <Poco/Net/DatagramSocket.h> #include <Poco/Net/SocketAddress.h>…...

Spring AOP概念及其实现

一、什么是AOP 全称Aspect Oriented Programming&#xff0c;即面向切面编程&#xff0c;AOP是Spring框架的第二大核心&#xff0c;第一大为IOC。什么是面向切面编程&#xff1f;切面就是指某一类特定的问题&#xff0c;所以AOP也可以称为面向特定方法编程。例如对异常的统一处…...

业务部绩效考核关键指标与数据分析

在业务部的绩效考核中&#xff0c;重点通过销售额、客户关系、财务管理等多个维度来评估团队的工作成果。绩效考核指标&#xff08;KPI&#xff09;不仅帮助公司衡量销售团队的业绩&#xff0c;还能反映出团队在客户管理、财务控制以及市场拓展方面的综合表现。每一个考核指标都…...

线上婚恋相亲小程序源码介绍

​基于ThinkPHP、FastAdmin和UniApp开发的线上婚恋相亲小程序源码&#xff0c;这款小程序源码采用了ThinkPHP作为后端框架&#xff0c;其强大的功能与良好的扩展性为程序的稳定运行提供了保障。 ​FastAdmin作为后台管理框架&#xff0c;使得管理员能够便捷地对用户信息、相亲…...

【SystemC初认识】SystemC是什么?有哪些主要组件?如何简单使用?

【SystemC初认识】SystemC是什么&#xff1f;有哪些主要组件&#xff1f;如何简单使用&#xff1f; 1 SystemC简介2 主要组件3 关于时序与调度4 如何安装4.1 安装C编译器4.2 安装SystemC 库 5 SystemC代码示例6 关于SystemC 仿真与调度7 SystemC 中的常用类和函数8 常见的设计模…...

软考:硬件中的CPU架构、存储系统(Cache、虚拟内存)、I/O设备与接口

文章目录 1. 引言1.1 硬件知识的重要性1.2 软件设计师考试中硬件的考察目标 2. CPU架构2.1 CPU的基本概念2.2 CPU的内部结构2.3 CPU的工作原理2.4 指令集架构&#xff08;ISA&#xff09;2.5 多核处理器 3. 存储系统3.1 存储器的基本概念3.2 主存储器&#xff08;RAM&#xff0…...

力扣hot100——98.验证二叉搜索树

题目链接&#xff1a;98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 首先列举一个错误代码 class Solution { public:bool isValidBST(TreeNode* root) {if(rootnullptr) return true;if(root->right){if(root->right->val<root->val) return f…...