欺诈文本分类检测(十四):GPTQ量化模型

1. 引言

量化的本质:通过将模型参数从高精度(例如32位)降低到低精度(例如8位),来缩小模型体积。

本文将采用一种训练后量化方法GPTQ,对前文已经训练并合并过的模型文件进行量化,通过比较模型量化前后的评测指标,来测试量化对模型性能的影响。

GPTQ的核心思想在于:将所有权重压缩到8位或4位量化中,通过最小化与原始权重的均方误差来实现。在推理过程中,它将动态地将权重解量化为float16,以提高性能,同时保持较低的内存占用率。

注:均方误差是评估两个数值数据集之间差异的一种常用方法,它通过计算量化后权重与原始权重之间的均方误差,并使之最小化,来减少量化过程中引入的误差,以保持模型在推理时的性能。

2. 量化过程

2.1 加载量化模型

首先引入必要的包,其中:

  • auto_gptq: 一个用于模型量化的库,通常用于减少模型的内存占用和计算消耗。
  • AutoGPTQForCausalLM: 用于加载和使用经过量化的因果语言模型。
  • BaseQuantizeConfig: 定义量化模型时所需的参数,例如量化精度。
  • AutoTokenizer:transformers库提供的分词器,用于处理文本分词。
import os
import json
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizer

定义量化任务要使用的设备,并指定模型的原始路径model_path

os.environ["CUDA_VISIBLE_DEVICES"] = "1"
device = 'cuda'
model_path = "/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0"

配置量化参数。

quantize_config = BaseQuantizeConfig(
    bits=8, 
    group_size=128,   # 分组量化
    damp_percent=0.01,
    desc_act=False,  
    static_groups=False,
    sym=True,
    true_sequential=True,
    model_name_or_path=None,
    model_file_base_name="model"
)

参数释义如下:

  • bits: 指定量化的位数为8位。
  • group_size:量化时的分组大小,分组量化可以提高计算效率,通常设置为 128 是一个合理的选择,适合大多数模型。
  • damp_percent:控制量化过程中对权重的平滑处理,防止过度量化导致的性能下降。默认值 0.01 通常是一个良好的起点,如果量化不佳,可以增加此值。
  • desc_act:控制是否使用描述性激活,设置为 False 可以加速推理,如果模型的精度更重要,可以设置为 True。
  • static_groups: 是否使用静态分组。静态分组可以提高推理效率, 如果模型结构固定且不需要动态调整,可以设置为 True。否则,保持为 False 以支持动态分组。
  • sym: 指定是否使用对称量化。对称量化可以简化计算,如果模型对称性较好,可以设置为 True。
  • true_sequential: 控制是否使用真实的顺序量化。真实顺序量化可以提高模型的表现,但可能会增加计算复杂性。如果模型对顺序敏感,可以设置为 True。
  • model_file_base_name:指定生成的量化模型文件名称,最终体现在输出文件的命名上。

加载分词器,并根据配置quantize_config指定的量化位数来加载模型。

tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config)
2.2 准备校准数据集

GPTQ采用权重分组量化(如上面的配置中128列为一组),一个分组内的参数采用逐个进行量化(如下图所示),在每个参数被量化后,需要适当调整这个 block 内其他未量化的参数,以弥补量化造成的精度损失。

在这里插入图片描述

因此,GPTQ 量化需要准备校准数据集,我们这里采用一个以前生成的测试数据集作为校准数据。

def load_jsonl(path):
    conversations = []
    with open(path, 'r') as file:
        data = [json.loads(line) for line in file]
        conversations = [dialog['messages'] for dialog in data]
        return conversations

eval_data_path = '/data2/anti_fraud/dataset/test_chatml_0815.jsonl'
conversations = load_jsonl(eval_data_path)
conversations[0]

校验数据集的数据格式是一个标准的聊天模板,示例如下:

[{'role': 'system', 'content': 'You are a helpful assistant.'},
 {'role': 'user',
  'content': '\n下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true/false)。\n\n\n发言人3: 那就是说看上半年我们的三四月份会不会有一些这个相关的一些这个缓解,就是说这方面的一些矛盾的一些缓解,债务的一个情况的一些缓解,那我们还要继续观察。\n发言人2: 好的,蒋总,那我们看一下那个其他投资者有没有什么其他问题。\n发言人1: 大家好,通过网络端接入的投资者可点击举手连麦等候提问,或在文字交流区提交您的问题,通过电话端接入的投资者请按星一键提问。先按星号键,再按一键,谢谢。大家好,通过网络端接入的投资者可点击举手连麦,然后提问,或在文字交流区提交您的问题。通过电话端接入的投资者请按星一键提问。\n发言人1: 先按星号键,再按数字一键,谢谢。'},
 {'role': 'assistant', 'content': '{"is_fraud": false}'}]

定义一个预处理函数,将文本数据预处理为张量数据。

def preprocess(dataset, max_len=1024):
    data = []
    for msg in dataset:
        text = tokenizer.apply_chat_template(msg, tokenize=False, add_generation_prompt=False)
        model_inputs = tokenizer([text])
        input_ids = torch.tensor(model_inputs.input_ids[:max_len], dtype=torch.int)
        data.append(dict(input_ids=input_ids, attention_mask=input_ids.ne(tokenizer.pad_token_id)))
    return data

dataset = preprocess(conversations)
  • tokenizer.apply_chat_template:负责将消息格式转化为Qwen模型需要的提示词格式。
  • tokenizer([text]):使用tokenizer对文本进行分词,并将token转换为ID值。
  • torch.tensor:将token_id转换为tensor张量。

配置日志显示格式:

import logging

logging.basicConfig(
    format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
)
2.3 开始量化

使用校准数据集来动态调整量化参数,使模型在量化时学习并适应数据分布。

%%time
model.quantize(dataset, cache_examples_on_gpu=False)
INFO - Start quantizing layer 1/28
INFO - Quantizing self_attn.k_proj in layer 1/28...
INFO - Quantizing self_attn.v_proj in layer 1/28...
INFO - Quantizing self_attn.q_proj in layer 1/28...
INFO - Quantizing self_attn.o_proj in layer 1/28...
INFO - Quantizing mlp.up_proj in layer 1/28...
INFO - Quantizing mlp.gate_proj in layer 1/28...
INFO - Quantizing mlp.down_proj in layer 1/28...
INFO - Start quantizing layer 2/28
……
INFO - Start quantizing layer 28/28
INFO - Quantizing self_attn.k_proj in layer 28/28...
INFO - Quantizing self_attn.v_proj in layer 28/28...
INFO - Quantizing self_attn.q_proj in layer 28/28...
INFO - Quantizing self_attn.o_proj in layer 28/28...
INFO - Quantizing mlp.up_proj in layer 28/28...
INFO - Quantizing mlp.gate_proj in layer 28/28...
INFO - Quantizing mlp.down_proj in layer 28/28...


CPU times: user 30min 52s, sys: 3min 40s, total: 34min 32s
Wall time: 27min 23s

由于内容太长,中间作了省略,不过仍然可以看出,量化是一层一层逐个对每个矩阵分别进行量化的,一个1.5B的模型量化过程耗时达27分钟。

保存量化后的模型和分词器状态。

  • quant_path指定了量化模型的保存路径
  • use_safetensors=True 参数表示使用安全张量格式(SafeTensors)进行保存,具有更好的安全性和性能。
  • tokenizer.save_pretrained为量化后的模型保存一份分词器配置。
quant_path = "/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8"
model.save_quantized(quant_path, use_safetensors=True)
tokenizer.save_pretrained(quant_path)

输出保存的分词器配置。

    ('/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/tokenizer_config.json',
     '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/special_tokens_map.json',
     '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/vocab.json',
     '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/merges.txt',
     '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/added_tokens.json',
     '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/tokenizer.json')
2.4 4位量化

上面是采用8位量化,作为对比,我们也量化一个4位模型,与8位量化的区别只在于量化配置时的参数bits改成了4,其它都不作改变.

quantize_config_int4 = BaseQuantizeConfig(
    bits=4,           # 4位量化
    group_size=128,   # 分组量化
    damp_percent=0.01,
    desc_act=False,  
    static_groups=False,
    sym=True,
    true_sequential=True,
    model_name_or_path=None,
    model_file_base_name="model"
)

采用4位量化配置来加载模型。

model_int4 = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config_int4)

对4位参数进行量化校验,校准数据集复用前面8位量化时生成的数据。

%%time
model_int4.quantize(dataset, cache_examples_on_gpu=False)
INFO - Start quantizing layer 1/28
INFO - Quantizing self_attn.k_proj in layer 1/28...
INFO - Quantizing self_attn.v_proj in layer 1/28...
INFO - Quantizing self_attn.q_proj in layer 1/28...
INFO - Quantizing self_attn.o_proj in layer 1/28...
INFO - Quantizing mlp.up_proj in layer 1/28...
INFO - Quantizing mlp.gate_proj in layer 1/28...
INFO - Quantizing mlp.down_proj in layer 1/28...
INFO - Start quantizing layer 2/28
……
INFO - Start quantizing layer 28/28
INFO - Quantizing self_attn.k_proj in layer 28/28...
INFO - Quantizing self_attn.v_proj in layer 28/28...
INFO - Quantizing self_attn.q_proj in layer 28/28...
INFO - Quantizing self_attn.o_proj in layer 28/28...
INFO - Quantizing mlp.up_proj in layer 28/28...
INFO - Quantizing mlp.gate_proj in layer 28/28...
INFO - Quantizing mlp.down_proj in layer 28/28...


CPU times: user 37min 11s, sys: 3min 2s, total: 40min 13s
Wall time: 31min 56s

保存量化后的模型和分词器配置。

quant_int4_path = "/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4"
model_int4.save_quantized(quant_int4_path, use_safetensors=True)
tokenizer.save_pretrained(quant_int4_path)
('/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/tokenizer_config.json',
 '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/special_tokens_map.json',
 '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/vocab.json',
 '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/merges.txt',
 '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/added_tokens.json',
 '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/tokenizer.json')

3. 评测

与前文不同,这里统一采用测试数据集进行评测,以评估模型的最终性能。

原始模型评测(16位)
%run evaluate.py
testdata_path = '/data2/anti_fraud/dataset/test0819.jsonl'
evaluate(model_path, '', testdata_path, device, batch=True, debug=True)
progress: 100%|██████████| 2349/2349 [01:52<00:00, 20.87it/s]

tn:1136, fp:31, fn:162, tp:1020
precision: 0.9705042816365367, recall: 0.8629441624365483

这时的召回率recall0.8629和前文的测评结果0.9129有差异,前文用的验证集,这里用的是测试集,可能是这两个数据集的数据分布不均匀,导致两者结果有较大差异。

量化8位模型评测
%run evaluate.py
testdata_path = '/data2/anti_fraud/dataset/test0819.jsonl'
model_int8_path = '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8'
evaluate(model_gptq_path, '', testdata_path, device, batch=True, debug=True)
tn:1134, fp:33, fn:158, tp:1024
precision: 0.9687795648060549, recall: 0.8663282571912013

8位量化模型的评测结果与原始模型基本一致,说明8位量化依然保持了原始模型的推理表现。

量化4位模型评测
%run evaluate.py
testdata_path = '/data2/anti_fraud/dataset/test0819.jsonl'
model_int4_path = '/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4'
tokenizer = AutoTokenizer.from_pretrained(model_int4_path)
model_int4_reload = AutoModelForCausalLM.from_pretrained(model_int4_path, device_map=device)
evaluate_with_model(model_int4_reload, tokenizer, testdata_path, device, batch=True, debug=True)

注:4位量化模型这里之所以要单独加载model,是因为GPTQ量化的4位模型有个限制——只能在GPU上运行,我们原先的加载方式会报错,详情可以参看本文最后的附:4位量化模型加载错误

tn:1081, fp:86, fn:50, tp:1132
precision: 0.9293924466338259, recall: 0.9576988155668359

从这个结果来看,4位量化模型与原始模型的性能差别较大,具体体现在:

  1. 精确率下降明显,表明模型在检测欺诈文本时,误报(false positives)数量增加,模型可能会将更多的非欺诈文本错误地分类为欺诈文本。
  2. 召回率上升,模型在检测欺诈时漏报(false negatives)的数量减少,这意味着模型在检测欺诈文本时更加激进,尽可能减少漏报,哪怕误报增加。

4位量化比8位量化引入更多的信息丢失和噪声,模型权重和激活值的精度显著下降,最终导致分类效果的明显差异。

4. 模型文件差异

原始模型文件列表信息:

!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0
    total 3026376
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua         80 Aug 29 11:30 added_tokens.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua        748 Aug 29 11:30 config.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua        242 Aug 29 11:30 generation_config.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua    1671853 Aug 29 11:30 merges.txt
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1975314632 Aug 29 11:30 model-00001-of-00002.safetensors
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1112152304 Aug 29 11:30 model-00002-of-00002.safetensors
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua      27693 Aug 29 11:30 model.safetensors.index.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua        367 Aug 29 11:30 special_tokens_map.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua       1532 Aug 29 11:30 tokenizer_config.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua    7028043 Aug 29 11:30 tokenizer.json
    -rw-rw-r-- 1 xiaoguanghua xiaoguanghua    2776833 Aug 29 11:30 vocab.json

8位量化模型的文件列表信息:

!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8
total 2235860
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua         80 Sep 10 11:53 added_tokens.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua       1062 Sep 10 11:53 config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    1671853 Sep 10 11:53 merges.txt
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 2278014312 Sep 10 11:53 model.safetensors
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua        269 Sep 10 11:53 quantize_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua        367 Sep 10 11:53 special_tokens_map.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua       1532 Sep 10 11:53 tokenizer_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    7028043 Sep 10 11:53 tokenizer.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    2776833 Sep 10 11:53 vocab.json

4位量化模型的文件列表信息:

!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4
total 1591120
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua         80 Sep 10 12:50 added_tokens.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua       1088 Sep 10 18:12 config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    1671853 Sep 10 12:50 merges.txt
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1617798120 Sep 10 12:50 model.safetensors
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua        269 Sep 10 12:50 quantize_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua        367 Sep 10 12:50 special_tokens_map.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua       1532 Sep 10 12:50 tokenizer_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    7028043 Sep 10 12:50 tokenizer.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua    2776833 Sep 10 12:50 vocab.json

可以看到,原始模型、8位量化、4位量化三者的模型文件大小分别3.08GB、2.27GB、1.61GB,量化位数越小,模型文件相应也越小。

另外还可以看到,模型文件大小与量化位宽的比例并不完全是线性关系。因为除了模型参数本身之外,还有模型架构、框架开销(pytorch)、优化器的动量和梯度信息等,这些都会影响着模型文件的总大小。

小结:本文通过gptq方法分别对微调后的模型进行了8位量化和4位量化,并对比了量化前后模型的性能指标差异,8位量化模型的性能指标变化小,而4位量化模型的性能指标变异较大。就我们这个场景来说,更适合采用8位量化模型。

附1:4位量化模型加载错误

使用如下代码进行先CPU加载再移到目标GPU时会报Found modules on cpu/disk错误:

model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16).eval().to(device)

错误详情:

ValueError: Found modules on cpu/disk. Using Exllama or Exllamav2 backend requires all the modules to be on GPU.You can deactivate exllama backend by setting `disable_exllama=True` in the quantization config object

原因:使用GPTQ方式量化int4模型时使用了exllama,这是一种高效的kernel实现,但需要所有模型参数在GPU上,因此对于GPTQ的4位量化模型,先使用CPU加载再移到GPU这种做法行不通。

解法

  1. 在模型目录下的config.json文件中,在quantization_config配置块中设置disable_exllama=true或者use_exllama=false,来禁用exllama,不过可能会影响推理速度。
  2. 在加载模型时直接加载到GPU上,类似from_disk = AutoModelForCausalLM.from_pretrained(path, device_map="cuda:0")

附2:偏置参数未使用警告

在加载4位量化模型时会报此警告,详细信息如下:

Some weights of the model checkpoint at /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4 were not used when initializing Qwen2ForCausalLM: ['model.layers.0.mlp.down_proj.bias', 'model.layers.0.mlp.gate_proj.bias', 'model.layers.0.mlp.up_proj.bias',
……
'model.layers.9.self_attn.o_proj.bias']

此问题的原因暂时未找到,哪位小伙伴知道原因有劳告知。
这个网页上有人报类似问题,但未说明原因:https://github.com/QwenLM/Qwen2/issues/239

参考资料

  • 欺诈文本分类检测(十一):LLamaFactory多卡微调
  • 欺诈文本分类检测(十二):模型导出与部署
  • 大模型量化技术原理
  • Found modules on cpu/disk错误讨论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/874560.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

判断奇偶数的小妙招

要判断一个数是奇数还是偶数&#xff0c;一般首先想到的都是对2取余&#xff0c;但其实有更高明的算法。 首先咱们要知道一个知识点&#xff1a;偶数的二进制末位为0&#xff0c;奇数的二进制末位为1。 这是进位制本身的规则决定的&#xff0c;二进制是“逢二进一”。如果末位…

Docker 学习 Day 2

docker 基本命令和操作 学习视频一、docker 常用命令1、帮助启动类命令2、镜像命令2.1、docker images2.2、docker search 某个 xxx 镜像的名字2.3、docker pull 某个 xxx 镜像的名字2.4、docker system df2.5、docker rmi 某个 xxx 镜像的名字 ID2.6、面试题&#xff1a;谈谈 …

谷歌seo网址如何快速被收录?

想让你的网站快速被搜索引擎收录&#xff0c;可以采取几种不同的策略。首先&#xff0c;确保你的网站内容丰富、有价值&#xff0c;搜索引擎更喜欢收录内容质量高的网站。同时&#xff0c;增强网站的外链建设&#xff0c;做好这些站内优化&#xff0c;接下来就是通过谷歌搜索控…

windows下自启springboot项目(jar+nginx)

1、将springboot项目打包为jar 2、新建文本文档 test.txt&#xff0c;并输入 java -jar D:\test\test.jar&#xff08;修改为自己的jar包位置&#xff09; 保存 然后修将后缀名改为 .bat 3、在同一目录再新建 文本文档test.txt&#xff0c;输入以下内容&#xff0c;&…

“杏鲍菇驱动机器人创新前行:康奈尔大学最新研究亮相Science子刊“

未来科技新篇章&#xff1a;杏鲍菇操控下的机器人奇旅&#xff01; 在这个日新月异的科技时代&#xff0c;你或许听说过机器人由AI驱动、由人脑操控&#xff0c;但你是否能想象&#xff0c;一颗看似平凡的杏鲍菇也能成为控制机器人的“大脑”&#xff1f; 没错&#xff0c;这不…

对抗性EM用于变分深度学习:在低剂量PET和低剂量CT中的半监督图像质量增强应用|文献速递--Transformer架构在医学影像分析中的应用

Title 题目 Adversarial EM for variational deep learning: Application to semi-supervised image quality enhancement in low-dose PET and low-dose CT 对抗性EM用于变分深度学习&#xff1a;在低剂量PET和低剂量CT中的半监督图像质量增强应用 01 文献速递介绍 医学影…

新专利:作物生长期预测方法及装置

近日,国家知识产权局正式授权了一项由北京市农林科学院智能装备技术研究中心、江苏省农业科学院联合申请的发明专利"作物生长期预测方法及装置"(专利号:ZL 2024 1 0185298.1)。该专利由 于景鑫 、任妮、吕志远、李友丽、吴茜等发明人耗时多年潜心研发&#xff0c;犹如…

6、关于Medical-Transformer

6、关于Medical-Transformer Axial-Attention原文链接&#xff1a;Axial-attention Medical-Transformer原文链接&#xff1a;Medical-Transformer Medical-Transformer实际上是Axial-Attention在医学领域的运行&#xff0c;只是在这基础上增加了门机制&#xff0c;实际上也就…

Java入门:08.Java中的static关键字01

1 static关键字 可以修饰属性变量&#xff0c;方法和代码段 static修饰的属性称为静态属性或类属性&#xff0c; 在类加载时就在方法区为属性开辟存储空间&#xff0c;无论创建多少个对象&#xff0c;静态属性在内存中只有一份。 可以使用 类名.静态属性 的方式引用 static修饰…

无人机动力系统设计之桨叶推力计算

无人机动力系统设计之桨叶推力计算 1. 源由2. 关键参数2.1 特性参数2.1.1 材质&#xff08;Material&#xff09;2.1.2 叶片数量&#xff08;Number of Blades&#xff09;2.1.3 重量&#xff08;Weight&#xff09;2.1.4 噪音水平&#xff08;Noise Level&#xff09; 2.2 安装…

一文为你详解期权波动率是什么?

今天期权懂带你了解一文为你详解期权波动率是什么&#xff1f;采用合适的期权组合来对冲或利用波动率变化带来的机会。不同策略适用于不同的市场条件和投资目标。 期权波动率 假如我们为地震灾害去买一份保险&#xff0c;你认为什么样地震的保险费会更贵呢&#xff0c;是深圳…

备忘录模式memento

学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/memento 允许生成对象状态的快照并在以后将其还原。备忘录不会影响它所处理的对象的内部结构&#xff0c; 也不会影响快照中保存的数据。

2024年湖北交安ABC公路安全员C证报考今时不同往日

2024年湖北交安ABC公路安全员C证报考今时不同往日 之前的交安ABC&#xff0c;你爱搭不理&#xff0c;现在的交安ABC&#xff0c;你高攀不起。真的应了这句话。所以建筑行业考证要趁早&#xff0c;别等要求严了你想报却缺东少西的。湖北交安ABC大变天了。 2024年之前报考湖北交…

初识Maven:Java项目管理工具

实际开发中&#xff0c;伴随着项目规模的增长&#xff0c;依赖管理和构建自动化变得至关重要&#xff0c;一套标准化的项目结构有助于更好的开发项目、简化这项任务&#xff08;真的不是强迫症&#xff09; Maven&#xff0c;作为 Apache Software Foundation 维护的项目管理工…

【Unity面经】性能优化篇

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 专栏交流&#x1f9e7;&…

SpringBoot开发——整合Logbook进行HTTP API请求响应日志输出

文章目录 1. 简介依赖管理2. 实战案例2.1 基本用法2.2 结合Logback日志记录到文件2.3 自定义核心类Logbook2.4 自定义日志输出Sink2.5 与RestTemplate集成1. 简介 记录HTTP API请求响应日志对于监控、调试和性能优化至关重要。它帮助开发者追踪API的使用情况,包括请求来源、参…

2010-2022年各省乡村振兴新质生产力相关变量数据(40+指标)

2010-2022年各省乡村振兴新质生产力相关变量数据&#xff08;40指标&#xff09; 1、时间&#xff1a;2010-2022年 2、来源&#xff1a;统计年鉴、能源统计年鉴、农村统计年鉴、人口和就业统计年鉴、城乡建设统计年鉴以及各省份统计年鉴 3、指标&#xff1a;省份、年份、分地…

洗袜子的小洗衣机哪款好?专洗袜子的微型洗衣机!洗衣机不要乱选

袜子洗衣机大多数都为迷你洗衣机&#xff0c;因为这是解决了用大洗衣机去洗袜子而大材小用的情况&#xff0c;同时袜子清洗的数量比较少&#xff08;满打满算一周的袜子5双&#xff0c;用迷你洗衣机清洗是绰绰有余的&#xff09;而现在也很多人为了洗袜子专门买一个迷你洗衣机&…

[论文笔记]LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale

引言 今天带来第一篇量化论文LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale笔记。 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比如替换"作者"为"我们"。 大语言模型已被广泛采用&#xff0c;但推理时需要大量的GPU内…

【Hadoop|MapReduce篇】MapReduce概述

1. MapReduce定义 MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个Hadoop集群上。 2. Map…