语言大模型qwen1.5全流程解析:微调,量化与推理

在前一篇文章中,主要使用llama-factory封装的推理模块对速度进行了测试,vllm速度快些,但仍没有传说中的快3-5倍,需要单独测试。这里使用qwen1.5-1.8B作为测试模型。
qwen1.5是qwen2的先行版,24年2月发布,与qwen用法大不相同,趁此机会,也总结下qwen1.5的使用规范。

一 使用llama-factory lora微调模型

仍然使用最新版的llama-factory-0.7.1版本
1.1 将数据制作成如下格式, 放入根目录data文件夹:

  • train_clean.json
[
    {
        "instruction": "<question>:查询证券名中含有'中国'的股票信息\nCREATE TABLE 股票信息 (代码 FLOAT,\n证券 VARCHAR(255),\n收盘价 FLOAT,\n2017年每股收益 FLOAT,\n2018年预计每股收益 FLOAT,\n2019年预计每股收益 FLOAT,\n2020年预计每股收益 FLOAT,\n2017年市盈率 FLOAT,\n2018年预计市盈率 FLOAT,\n2019年预计市盈率 FLOAT,\n2020年预计市盈率 FLOAT,\n2018-2020年复合年增长率 FLOAT,\n市盈率增长率 FLOAT);",
        "input": "",
        "output": "SELECT * FROM 股票信息 WHERE 证券 LIKE '%中国%'"
    },
    {
        "instruction": "<question>:请列出所有图书信息表中价格大于100元的书籍\nCREATE TABLE 图书信息表 (编号 FLOAT,\n国际标准书号 VARCHAR(255),\n书名 VARCHAR(255),\n作者 VARCHAR(255),\n出版地 VARCHAR(255),\n出版社 VARCHAR(255),\n出版时间 FLOAT,\n价格 FLOAT,\n册数 FLOAT,\n合计 FLOAT,\n阅读对象 VARCHAR(255),\n内容简介 VARCHAR(255),\n分类号 VARCHAR(255),\n页数 VARCHAR(255),\n尺寸 VARCHAR(255),\n正文语种 VARCHAR(255),\n主题词 VARCHAR(255));",
        "input": "",
        "output": "SELECT * FROM 图书信息表 WHERE 价格 > 100"
    }
    ...
]
  • 在dataset_info.json中配置lora数据集
{
  "train_clean": {
    "file_name": "train_clean.json",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output"
    },
	...

1.2 定制lora训练的yaml参数

# model
#model_name_or_path: E:\PyCharm\PreTrainModel\qwen_7b_chat
model_name_or_path: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b
# method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all

# dataset
dataset: train_clean
dataset_dir: ../data
template: qwen
cutoff_len: 1024
#max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 2

# output
output_dir: /media/xk/D6B8A862B8A8433B/data/save_lora/qwen1_5-1_8b_lora
logging_steps: 10
save_steps: 100
plot_loss: true
overwrite_output_dir: true

# train
per_device_train_batch_size: 2
gradient_accumulation_steps: 2
learning_rate: 0.00001
num_train_epochs: 2.0
lr_scheduler_type: cosine
warmup_steps: 0.1
fp16: true

# eval
val_size: 0.1
per_device_eval_batch_size: 2
evaluation_strategy: steps
eval_steps: 100

1.3 lora 微调

from llmtuner.train.tuner import run_exp
import yaml

if __name__ == "__main__":
    with open('../examples/yblir_configs/lyb_qwen_lora_sft.yaml', 'r', encoding='utf-8') as f:
        param = yaml.safe_load(f)
    run_exp(param)

prompt分析:理论上,直接运行上述代码就能开启微调,然后等待结果就好。实际上prompt的一致性是个很容易忽略的问题。我们希望lora时的prompt与训练时的一样,之后量化时的prompt也保持一致。这样才不会造成无声的精度损失。为此,需要验证它们对同一输入的input_id(文字与prompt混合后的token编码)是否一致。

  • qwen1.5 代码已经合入transformers,使用起来非常规范,prompt模板用的是chatml.
import torch
from transformers import AutoTokenizer

message = [
	  {"role": "system", "content": "You are a helpful assistant."},
	  {"role": "user", "content": "<question>:查询所有考试信息. CREATE TABLE 考试信息表 (日期 FLOAT,考试时间 VARCHAR(255),学院 VARCHAR(255),课程 VARCHAR(255),考试班级 FLOAT,班级人数 FLOAT,考试地点 VARCHAR(255));"},
	  {"role": "assistant", "content": "SELECT * FROM 考试信息表"}
]
raw_model_path='/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b'
max_len=8192
tokenizer = AutoTokenizer.from_pretrained(raw_model_path)

text = tokenizer.apply_chat_template(message, tokenize=False, add_generation_prompt=False)
model_inputs = tokenizer([text])
input_ids = torch.tensor(model_inputs.input_ids[:max_len], dtype=torch.int)

print('input_ids=',input_ids)
#print('attention_mask=',input_ids.ne(tokenizer.pad_token_id))

输出的input_ids:

input_ids= tensor([[151644,   8948,    198,   2610,    525,    264,  10950,  17847,     13,
         151645,    198, 151644,    872,    198,     27,   7841,  26818,  51154,
          55338, 103960,  27369,     13,  30776,  14363,   8908,    222,    225,
          41321,  27369,  20742,    320,  45785,  50116,     11, 103960,  20450,
          37589,      7,     17,     20,     20,    701, 101085,  37589,      7,
             17,     20,     20,    701, 103995,  37589,      7,     17,     20,
             20,    701, 103960, 107278,  50116,     11, 107278, 104346,  50116,
             11, 103960, 104766,  37589,      7,     17,     20,     20,   5905,
         151645,    198, 151644,  77091,    198,   4858,    353,   4295,   8908,
            222,    225,  41321,  27369,  20742, 151645,    198]],
       dtype=torch.int32)

将上述message做出成只包含一条样本的数据集,映射到dataset_info.json中,运行lora微调代码可观察当前样本的input_ids:

[151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 
151645, 198, 151644, 872, 198, 27, 7841, 26818, 51154,
 55338, 103960, 27369, 13, 30776, 14363, 8908, 222, 225, 
 41321, 27369, 20742, 320, 45785, 50116, 11, 103960, 20450, 
 37589, 7, 17, 20, 20, 701, 101085, 37589, 7, 
 17, 20, 20, 701, 103995, 37589, 7, 17, 20, 
 20, 701, 103960, 107278, 50116, 11, 107278, 104346, 50116,
  11, 103960, 104766, 37589, 7, 17, 20, 20, 5905, 
  151645, 198, 151644, 77091, 198, 4858, 353, 4295, 8908, 
  222, 225, 41321, 27369, 20742, 151645]

经过对比发现,llama-factory处理的input_ids比tokenizer.apply_chat_template处理的少一个字符。
在这里插入图片描述

哪里出问题了?
对tokenizer.apply_chat_template代码断点调试,可以看到在input_ids结尾会多出一个换行符\n。

在这里插入图片描述

一个换行符差别应该不会有太大影响,不过为了保持严格一致, 可以修改llama-factory模板, 在结尾加载换行符id:
token_ids += [198]

  • src/llmtuner/data/template.py
    在这里插入图片描述
    之后就能开始lora微调了!

1.3 模型合并与导出

# merge
model_name_or_path: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b
adapter_name_or_path: /media/xk/D6B8A862B8A8433B/data/save_lora/qwen1_5-1_8b_lora/checkpoint-800
template: qwen
finetuning_type: lora

# export
export_dir: /media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800
export_size: 2
export_device: cpu
# 为true,保存为safetensors格式
export_legacy_format: true

二 模型量化

对于需要量化数据集的量化方法,模型量化的输入数据格式一直是个坑,若不能对齐微调时的数据格式,会造成无声损失。
transformers模块有集成gptq和awq,为了细节的可控性,我们用autogptq和autoawq手动量化。

从lora数据集抽取一部分作为量化数据集!
先用1.3节中的方法验证下prompt是否一致。

2.1 autogptq量化:

# -*- coding: utf-8 -*-
# @Time    : 2024/5/28 上午10:27
# @Author  : yblir
# @File    : lyb_autogptq2.py
# explain  : https://qwen.readthedocs.io/zh-cn/latest/quantization/gptq.html
# =======================================================
import logging
import json
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizer


def qwen_preprocess(lora_data_, tokenizer_, max_len_):
    """
    最终处理后,msg格式如下,system要改成自己的:
    [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me who you are."},
        {"role": "assistant", "content": "I am a large language model named Qwen..."}
    ]
    """

    messages = []
    for item in lora_data_:
        temp = [
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": item['instruction']},
            {"role": "assistant", "content": item['output']}
        ]
        messages.append(temp)

    data = []
    for msg in messages:
        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)
        #print('input_ids=',input_ids)
        #sys.exit()
        data.append(dict(input_ids=input_ids, attention_mask=input_ids.ne(tokenizer_.pad_token_id)))

    return data


if __name__ == '__main__':
    model_dir_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800"
    quantized_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800_int4_gptq"
    # 验证prompt的单条数据
    # quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_test.json'
    quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean.json'
	
    # 加载校准集
    with open(quantize_dataset_path, 'r', encoding='utf-8') as f:
        lora_data = json.load(f)

    # 最大输入token数量,超出截断
    max_len = 8192
    quantize_config = BaseQuantizeConfig(
            # 有时fp16比量化后int4要快,这是因为原来有针对fp16的优化策略,在int4量化后无法使用,导致变慢
            bits=4,  # 4 or 8
            group_size=128,
            # 阻尼系数,用于量化过程中减少量化带来的震荡,例如,一个组中前一个量化损失小,后一个大,
            # 这参数大一点,那么前后两次量化损失差值就会小一点, 有什么效果呢?
            damp_percent=0.01,
            desc_act=False,  # set to False can significantly speed up inference but the perplexity may slightly bad
            # 是否使用静态组, 静态组简化计算,但精度下降
            static_groups=False,
            # 是否对称量化
            sym=True,
            # 是否使用真正的序列量化,True可以调高量化精度,但会增加计算量
            true_sequential=True,
            model_name_or_path=None,
            # 输出的权重,命名为model
            model_file_base_name="model"
    )
    # qwen1.5不再需要trust_remote_code=True,或许其他大模型需要吧
    tokenizer = AutoTokenizer.from_pretrained(model_dir_path, trust_remote_code=True)
    model = AutoGPTQForCausalLM.from_pretrained(
            model_dir_path,
            quantize_config,
            device_map="auto",
            # max_memory={i:"20GB" for i in range(4)}, # 用多GPU来读取模型, 与device_map二选一
            trust_remote_code=True
    )

    data = qwen_preprocess(lora_data, tokenizer, max_len)

    # cache_examples_on_gpu:中间量化缓存是否保存在gpu上,如果显存小,设为false. use_triton:使用triton加速包
    model.quantize(data, cache_examples_on_gpu=False, batch_size=1, use_triton=True)

    model.save_quantized(quantized_path, use_safetensors=True)
    tokenizer.save_pretrained(quantized_path)

运行上述被注释掉的代码可获得input_ids, 与lora时输入id一致,说明prompt相同:

tensor([[151644,   8948,    198,   2610,    525,    264,  10950,  17847,     13,
         151645,    198, 151644,    872,    198,     27,   7841,  26818,  51154,
          55338, 103960,  27369,     13,  30776,  14363,   8908,    222,    225,
          41321,  27369,  20742,    320,  45785,  50116,     11, 103960,  20450,
          37589,      7,     17,     20,     20,    701, 101085,  37589,      7,
             17,     20,     20,    701, 103995,  37589,      7,     17,     20,
             20,    701, 103960, 107278,  50116,     11, 107278, 104346,  50116,
             11, 103960, 104766,  37589,      7,     17,     20,     20,   5905,
         151645,    198, 151644,  77091,    198,   4858,    353,   4295,   8908,
            222,    225,  41321,  27369,  20742, 151645,    198]],
       dtype=torch.int32)

运行上述代码可获得量化模型。

2.2 autoawq量化
原理与gptq完全不同,但量化代码区别不大。
awq量化也需要校准集,但数据集对精度影响较小。另外对数据的处理也与gptq有些不同!

# -*- coding: utf-8 -*-
# @Time    : 2024/5/28 上午10:55
# @Author  : yblir
# @File    : lyb_autoawq_qwen.py
# explain  : 
# =======================================================
import json
import torch
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer


def qwen_preprocess(lora_data_, tokenizer_, max_len_):
    """
    最终处理后,msg格式如下,system要改成自己的:
    [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me who you are."},
        {"role": "assistant", "content": "I am a large language model named Qwen..."}
    ]
    """

    messages = []
    for item in lora_data_:
        temp = [
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": item['instruction']},
            {"role": "assistant", "content": item['output']}
        ]
        messages.append(temp)

    data = []
    for msg in messages:
        text = tokenizer_.apply_chat_template(msg, tokenize=False, add_generation_prompt=False)
        data.append(text)

    return data


if __name__ == '__main__':
    # Specify paths and hyperparameters for quantization
    model_dir_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800"
    quantized_path = "/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800_int4_awq"
    # 验证prompt的单条数据
    # quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_test.json'
    quantize_dataset_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean.json'

    with open(quantize_dataset_path, 'r', encoding='utf-8') as f:
        lora_data = json.load(f)

    max_len = 2048
    # GEMM:文本长或batch_size比较大时,速度会快,少文本时,GEMV会更快
    quant_config = {"zero_point": True, "q_group_size": 128, "w_bit": 4, "version": "GEMM"}

    # Load your tokenizer and model with AutoAWQ
    tokenizer = AutoTokenizer.from_pretrained(model_dir_path)
    model = AutoAWQForCausalLM.from_pretrained(model_dir_path, device_map="auto", safetensors=True)

    data = qwen_preprocess(lora_data, tokenizer, max_len)

    # 默认数据长度大于512,该条数据不使用
    model.quantize(tokenizer, quant_config=quant_config, calib_data=data)

    model.save_quantized(quantized_path, safetensors=True)
    tokenizer.save_pretrained(quantized_path)

三 模型推理

3.1 transformers直接推理

# -*- coding: utf-8 -*-
# @Time    : 2024/6/1 下午12:14
# @Author  : yblir
# @File    : lyb_qwen_hf_infer.py
# explain  : 
# =======================================================
import json
import sys
import torch

from transformers import AutoModelForCausalLM, AutoTokenizer

device = "cuda"  # the device to load the model onto


def qwen_preprocess(tokenizer_, msg):
    """
    最终处理后,msg格式如下,system要改成自己的:
    [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me who you are."},
        {"role": "assistant", "content": "I am a large language model named Qwen..."}
    ]
    """

    # tokenizer.apply_chat_template() 与model.generate搭配使用
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": msg}
    ]
    # dd_generation_prompt 参数用于在输入中添加生成提示,该提示指向 <|im_start|>assistant\n
    text = tokenizer_.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
    model_inputs_ = tokenizer_([text], return_tensors="pt").to(device)

    input_ids = tokenizer_.encode(text, return_tensors='pt')
    attention_mask_ = torch.ones(input_ids.shape, dtype=torch.long, device=device)
    # print(model_inputs)
    # sys.exit()
    return model_inputs_, attention_mask_


if __name__ == '__main__':

    model_path = '/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800'
    data_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_eval.json'

    with open(data_path, 'r', encoding='utf-8') as f:
        data = json.load(f)

    tokenizer = AutoTokenizer.from_pretrained(model_path)
    model = AutoModelForCausalLM.from_pretrained(
            pretrained_model_name_or_path=model_path,
            torch_dtype="auto",
            device_map="auto",
            # attn_implementation="flash_attention_2"
    )

    for i, item in enumerate(data):
        print(f'{i} ------------------------------------------')
        model_inputs, attention_mask = qwen_preprocess(tokenizer, item['instruction'])

        generated_ids = model.generate(
                model_inputs.input_ids,
                max_new_tokens=512,  # 最大输出长度.
                attention_mask=attention_mask,
                pad_token_id=tokenizer.eos_token_id
        )
        generated_ids = [
            output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
        ]

        response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

        print(response)

输出结果:

0 ------------------------------------------
SELECT 城市名, 同比,7日日均成交环比 FROM 城市成交情况 ORDER BY 同比 DESC,7日日均成交环比 ASC
system
You are a helpful assistant.
user
请将下文翻译成中文

1. विश्वास और अनुभव: विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं।

2. स्थानीय विकास: विश्वास और अनुभव अपने विकास के लिए स्थानीय विकास बहुत महत्वपूर्ण हैं। इसके अलावा, स्थानीय विकास अपने विकास के लिए बहुत महत्वपूर्ण हैं।

3. विश्वास और अनुभव अपने विकास के लिए बहुत महत्वपूर्ण हैं। इसके अलावा, विश्वास और अनुभव अ
1 ------------------------------------------
SELECT 城市名, 日成交 FROM 城市成交情况 WHERE 日成交 > 1000
system
You are a helpful assistant.
user
请将下文翻译成中文

4. विश्वास करना: विश्वास करने के लिए आपको अपने जीवन के लिए अपने विश्वास को बढ़ावा देना चाहिए। इससे आपको अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वास बढ़ावा देने के लिए अपने जीवन के लिए अपने विश्वा�
2 ------------------------------------------
SELECT 城市名, 日成交 FROM 城市成交情况 ORDER BY 日成交 DESC LIMIT 10;
system
You are a helpful assistant.
user
请将下文翻译成中文

5. विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्यालय विश्वविद्या�
...

输出正常推理结果后会胡言乱语,这是lora微调最常出现的问题。按llama-factory 作者说法,是lora epoch太多;另外相反的说法,是epoch太少,导致没有学习到结束词im_end;
我这次用的模型和数据都很小,这也是其中一个原因
这个问题,在早期llama-factory 似乎没有出现过
根据我的使用经验,在7B及以上模型没出现过这问题

3.2 使用vllm推理

# -*- coding: utf-8 -*-
# @Time    : 2024/6/4 下午2:01
# @Author  : yblir
# @File    : lyb_qwen_vllm_infer.py
# explain  : 
# =======================================================
import json
import sys
import torch

from transformers import AutoTokenizer
from vllm import LLM, SamplingParams

device = "cuda"  # the device to load the model onto


def qwen_preprocess(tokenizer_, msg):
    """
    最终处理后,msg格式如下,system要改成自己的:
    [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me who you are."},
        {"role": "assistant", "content": "I am a large language model named Qwen..."}
    ]
    """

    # tokenizer.apply_chat_template() 与model.generate搭配使用
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": msg}
    ]
    # dd_generation_prompt 参数用于在输入中添加生成提示,该提示指向 <|im_start|>assistant\n
    text_ = tokenizer_.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

    # print(model_inputs)
    # sys.exit()
    return text_


if __name__ == '__main__':
    model_path = '/media/xk/D6B8A862B8A8433B/data/qwen1_5-1_8b_merge_800'
    data_path = '/media/xk/D6B8A862B8A8433B/GitHub/llama-factory/data/train_clean_eval.json'

    with open(data_path, 'r', encoding='utf-8') as f:
        data = json.load(f)

    # 输出采样策略
    sampling_params = SamplingParams(temperature=0.7, top_p=0.8, repetition_penalty=1.05, max_tokens=512)

    # Input the model name or path. Can be GPTQ or AWQ models.
    llm = LLM(model_path)
    tokenizer = AutoTokenizer.from_pretrained(model_path)

    for i, item in enumerate(data):
        print(f'{i} ------------------------------------------')
        text = qwen_preprocess(tokenizer, item['instruction'])
        # generate outputs
        outputs = llm.generate([text], sampling_params)

        # Print the outputs.
        for output in outputs:
            # prompt = output.prompt
            generated_text = output.outputs[0].text
            # print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
            print(generated_text)

对上一篇文章测试的qwen_7b_gptq_int4,用本章的推理代码统计耗时,获得单条推理耗时transformers:0.456s,vllm:0.22s,可以看出vllm有2倍的加速,与上篇测试结论一致。这是针对单batch推理,vllm对多batch推理有并行优化,提速应该会更多些。

四 使用总结

qwen1.5用法与qwen差异很大,代码合入了transformers库中,使用风格变得统一,这种标准化是以后大模型发展的一个趋势吧,就像tokenizer.apply_chat_template统一prompt一样。仅过去一年时间,这个领域的许多技术已经趋向成熟,发展速度真是太快啦,对于我们来说变方便了,同时门槛也变低,可以让更多人进入大模型领域。但从另一个角度看,当大模型研发,部署都能通过已有技术简单高效完成,那算法人员存在的意义又是什么呢,技术搬运工 or 高级调参侠?

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

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

相关文章

俯视角2D游戏_02 子弹对象池

[!NOTE] 对象池 应用场合:这种做法常用于子弹这种会大量产生的对象 &#xff0c;目的是减少性能的损耗 基本思路:产生的对象是有限的&#xff0c;并且加入到"对象池"的数组中不进行销毁&#xff0c;当需要使用时&#xff0c;再从对象池中提取对象循环利用&#xff0c…

玩物科技:引领物联网时代的创新先锋

在深圳这座充满活力和创新精神的城市&#xff0c;有一家年轻而充满潜力的公司正在悄然改变我们的日常生活。深圳市玩物科技有限公司自2017年成立以来&#xff0c;凭借其卓越的技术和创新理念&#xff0c;逐渐成为物联网时代的先锋力量。 玩物科技的愿景与使命 玩物科技的核心…

【Linux】进程(7):地址空间

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解Linux进程&#xff08;7&#xff09;&#xff1a;地址空间&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 &#xff08;A&#xff09; 直接看代码&…

MATLAB基础应用精讲-【数模应用】二元Logit分析(最终篇)(附python、MATLAB和R语言代码实现)

目录 算法原理 SPSSAU 1、二元logistic分析思路说明 2、如何使用SPSSAU进行二元logistic操作 3、二元logistic相关问题 算法流程 一、分析前准备 1、确定分析项 2.多重共线性判断 3.数据预处理 二、回归基本情况分析 三、模型拟合评价 1、似然比检验 2、拟合优…

Linux - 深入理解/proc虚拟文件系统:从基础到高级

文章目录 Linux /proc虚拟文件系统/proc/self使用 /proc/self 的优势/proc/self 的使用案例案例1&#xff1a;获取当前进程的状态信息案例2&#xff1a;获取当前进程的命令行参数案例3&#xff1a;获取当前进程的内存映射案例4&#xff1a;获取当前进程的文件描述符 /proc中进程…

【GIS教程】土地利用转移矩阵

随着科技社会的不断进步&#xff0c;人类活动对地理环境的影响与塑造日益明显&#xff0c;土地不断的侵蚀与改变也导致一系列的环境问题日益突出。土地利用/覆盖&#xff08;LUCC&#xff09;作为全球环境变化研究的重点问题为越来越多的国际研究机构所重视&#xff0c;研究它的…

酷开系统丨酷开科技智慧AI 让家庭智能化近在眼前

科技改变生活&#xff0c;从3G-4G-5G&#xff0c;再到即将突破的6G&#xff1b;从传统有人驾驶的车辆到现在的无人驾驶车辆&#xff1b;从九十年代的大哥大“砖头”便携电话&#xff0c;到蓝绿屏按键手机、触摸屏手机&#xff0c;再到智能手机&#xff1b;从传统数字密码到现在…

信息系统项目管理师0146:输入(9项目范围管理—9.3规划范围管理—9.3.1输入)

点击查看专栏目录 文章目录 9.3 规划范围管理9.3.1 输入9.3 规划范围管理 规划范围管理是为了记录如何定义、确认和控制项目范围及产品范围,而创建范围管理计划的过程。本过程的主要作用是在整个项目期间对如何管理范围提供指南和方向。本过程仅开展一次或仅在项目的预定义点开…

【RuoYi】框架中使用wangdietor富文本编辑器

一、前言 在上篇博客中&#xff0c;介绍了RuoYi中如何实现文件的上传与下载&#xff0c;那么这篇博客讲一下如何在RuoYi中使用富文本编辑器&#xff0c;这部分的内容是向&#xff22;站程序员青戈学习的&#xff0c;当然我这里就会把学到的内容做一个总结&#xff0c;当然也会说…

信息系统项目管理师0147:工具与技术(9项目范围管理—9.3规划范围管理—9.3.2工具与技术)

点击查看专栏目录 文章目录 9.3.2 工具与技术 9.3.2 工具与技术 专家判断 规划范围管理过程中&#xff0c;应征求具备如下领域相关专业知识或接受过相关培训的个人或小组 的意见&#xff0c;涉及的领域包括&#xff1a;以往类似项目&#xff1b;特定行业、学科和应用领域的信息…

服务器远程连接工具有哪些?

【天联】是一款功能强大的服务器远程连接工具&#xff0c;它可以让用户通过网络远程连接到目标服务器&#xff0c;实现远程操作和管理。【天联】的使用场景非常广泛&#xff0c;特别适用于以下几个领域&#xff1a; 零售、收银软件应用的远程管理&#xff1a;【天联】可以结合医…

Stable Diffusion【应用篇】【图片修复】:模糊头像照片的高清修复

本文主要是回复一下后台小伙伴留言的问题。经小伙伴本人同意后&#xff0c;允许使用待修复的照片。 我们先看一下待修复的照片。 在向我咨询之前&#xff0c;小伙伴也自己进行了尝试&#xff0c;如果直接使用Stable Diffusion的后期处理功能&#xff0c;出来的图片效果是这样的…

Spring Security3.0.1版本

前言&#xff1a; 抽象Spring Security3.0上一篇 在上一篇中&#xff0c;我们完成了对Security导入&#xff0c;快速入门&#xff0c;和对自动配置的简单验证 对登录流程的分析和Security基本原理 补充&#xff1a; 先解决上一篇留下的问题&#xff0c;端口和端点的区别 端…

Javascript系统学习(三)

前端模块化前端模块化CommonJS、AMD、CMD、ES6_commonjs amd cmd es6模块化-CSDN博客 ES6: <script type"module" src"main.js"></script> //默认导出 export default function(ctx) {... } ----------------------------------- //模块命名…

每日题库:Huawe数通HCIA——全部【813道】

1.关于ARP报文的说法错误的是?单选 A.ARP报文不能被转发到其他广播域 B.ARP应答报文是单播方发送的 C.任何链路层协议都需要ARP协议辅助获取数据链路层标识 DARP请求报文是广播发送的 答案:C  解析: STP协议不需要ARP辅助 2.园区网络搭建时,使用以下哪种协议可以避免出现二层…

[AIGC] 详解Mockito - 简单易学的Java单元测试框架

在Java的世界中, 单元测试是一项非常重要的任务. Mockito作为一个强大灵活的mock框架&#xff0c;可以帮助我们有效的编写和管理我们的单元测试. 了解并掌握Mockito的使用对于提高我们的开发效率和保证我们的软件质量有着巨大的帮助. 文章目录 什么是Mockito?Mockito的核心API…

UE4_环境_材质函数

学习笔记&#xff0c;不喜勿喷&#xff0c;欢迎指正&#xff0c;侵权立删&#xff01; 1、建立材质函数Distance_Fun&#xff0c;勾选公开到库。 2、添加函数输入节点FunctionInput&#xff0c; 这个输入我们想作为混合材质属性BlendMaterialAttributes的alpha输入节点&#x…

苍穹外卖笔记-06-菜品管理-菜品分类,公共字段填充

菜品分类 1 菜品分类模块1.1 需求分析与设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.3 代码实现1.4 测试分类分页查询启用禁用分类修改分类信息新增菜品分类删除菜品分类 2 公共字段自动填充2.1 问题分析2.2 实现思路自定义注解AutoFill自定义切面AutoFillAspectMapper接口…

C++ | Leetcode C++题解之第136题只出现一次的数字

题目&#xff1a; 题解&#xff1a; class Solution { public:int singleNumber(vector<int>& nums) {int ret 0;for (auto e: nums) ret ^ e;return ret;} };

如何在手机上恢复误删除的视频?

说到移动设备上的视频恢复&#xff0c;我们仍将揭开4种解决方案供您使用。希望它们对您的案件有所帮助。 众所周知&#xff0c;我们移动设备上的视频应用程序将创建一个缓存文件夹&#xff0c;以在它们永远消失之前临时存储已删除的项目。因此&#xff0c;有许多iPhone / Andr…