【李宏毅-生成式 AI】Spring 2024, HW5:LLM Fine-tuning 实验记录

文章目录

    • 1. Task Overview
    • 2. Overall Workflow
    • 3. Dataset 介绍
    • 4. 代码介绍
      • 4.1 环境介绍
      • 4.2 下载 dataset
      • 4.3 下载并加载模型
      • 4.2 Notebook 代码
        • 1)import 部分
        • 2)固定 seed
        • 3)加载 LLM
        • 4)加载 tokenizer
        • 5)设置解码参数
        • 6)⭐ LLM 和 tokenizer 使用示例
        • 7)generate_training_data 和 evaluate 函数
        • 8)demo examples
        • 9)Hyper Parameters
        • 10)model 的量化和 LoRA
        • 11)加载 dataset
        • 12)Trainer
        • 13)模型训练
        • 14)运行 test
    • 5. 总结

这个实验主要是 fine-tune 一个 LLM,让一个 LLM 能够写唐诗。

相关链接:

  • Slides:Slides | Google Drive
  • Code: colab
  • Dataset: GitHub
  • Video: Bilibili

1. Task Overview

给 AI 一首唐诗的前两个 sentences,我们希望它能够完成剩下的部分:

在这里插入图片描述
但是,原来的 LLM 可能并不具备这样的能力,我们希望经过 fine tune 之后,它能够最起码接一句像样的诗词:

在这里插入图片描述

2. Overall Workflow

LLM 使用 MediaTek-Research/Breeze-7B-Instruct-v0_1

MediaTek Research Breeze-7B (hereinafter referred to as Breeze-7B) is a language model family that builds on top of Mistral-7B, specifically intended for Traditional Chinese use.

数据集是一堆唐诗,一个 data point 的 example 如下:

在这里插入图片描述

总共有 5000 条数据。

微调的思路是:将一个 data point 的 instruction、input 和 output 填入 prompt template 中,形成一个 text,用来训练 LLM。

微调完成后,将 instruction、input 形成一个 prompt 输入给 LLM,让其完成剩下部分的唐诗。

3. Dataset 介绍

dataset 主要包含两个 JSON 文件:

  • Tang_testing_data.json:测试集,包含 15 条数据
  • Tang_training_data.json:训练集,包含 5001 条数据

其中训练集每一条数据的格式都是前面 example 展示的,而测试集只包含 instruction 和 input 字段,答案在 Tang_testing_gt.txt 文件中:

在这里插入图片描述

4. 代码介绍

4.1 环境介绍

Python 3.10,torch 2.3.1

其他依赖如下:

!pip install bitsandbytes==0.43.0
!pip install datasets==2.10.1
!pip install transformers==4.38.2
!pip install peft==0.9.0
!pip install sentencepiece==0.1.99
!pip install -U accelerate==0.28.0
!pip install colorama==0.4.6

具体的代码可以下载课程给的 notebook,并查看其中的代码。

4.2 下载 dataset

git clone https://github.com/CheeEn-Yu/GenAI-Hw5.git

4.3 下载并加载模型

由于从 HuggingFace 下载模型可能会失败,所以可以从镜像站先下载模型:

HuggingFace 镜像站:https://hf-mirror.com/

这里介绍如何使用 huggingface-cli 下载模型。

  • 安装依赖:pip install -U huggingface_hub
  • 设置 mirror 环境变量:export HF_ENDPOINT=https://hf-mirror.com
  • 设置 huggingface 的缓存目录:export HF_HOME=/root/autodl-tmp/cache/
  • 下载模型:huggingface-cli download --resume-download MediaTek-Research/Breeze-7B-Instruct-v0_1

下载完成后,可以在目录中看到下载的预训练模型:

所在的目录就是 ${HF_HOME}/hub/ 中,之后代码需要从这个目录中加载模型。

4.2 Notebook 代码

1)import 部分
import os
import sys
import argparse
import json
import warnings
import logging
warnings.filterwarnings("ignore")import torch
import torch.nn as nn
import bitsandbytes as bnb
from datasets import load_dataset, load_from_disk
import transformers, datasets
from peft import PeftModel
from colorama import *from tqdm import tqdm
from transformers import AutoTokenizer, AutoConfig, AutoModelForCausalLM, BitsAndBytesConfig
from transformers import GenerationConfig
from peft import (prepare_model_for_int8_training,LoraConfig,get_peft_model,get_peft_model_state_dict,prepare_model_for_kbit_training
)
2)固定 seed

固定住 seed 从而防止训练的不确定性:

seed = 42
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
torch.manual_seed(seed)
if torch.cuda.is_available():torch.cuda.manual_seed_all(seed)
3)加载 LLM

这里使用 transformers 库的 AutoModelForCausalLM 来加载模型,并需要将 cache_dir 设置为下载的模型的目录。

cache_dir = "/root/autodl-tmp/cache/hub"nf4_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_use_double_quant=True,bnb_4bit_compute_dtype=torch.bfloat16
)# 從指定的模型名稱或路徑載入預訓練的語言模型
model = AutoModelForCausalLM.from_pretrained(model_name,cache_dir=cache_dir,quantization_config=nf4_config,low_cpu_mem_usage = True
)
4)加载 tokenizer

加载 LLM 对应的 tokenizer:

# 創建 tokenizer 並設定結束符號 (eos_token)
logging.getLogger('transformers').setLevel(logging.ERROR)
tokenizer = AutoTokenizer.from_pretrained(model_name,add_eos_token=True,cache_dir=cache_dir,quantization_config=nf4_config
)
tokenizer.pad_token = tokenizer.eos_token

将 tokenizer 的 padding token 设定为 0:

tokenizer.pad_token_id = 0
5)设置解码参数

设置模型做 inference 时的 decoding 参数:

# 設定模型推理時需要用到的decoding parameters
max_len = 128
generation_config = GenerationConfig(do_sample=True,temperature=0.1,num_beams=1,top_p=0.3,no_repeat_ngram_size=3,pad_token_id=2,
)
6)⭐ LLM 和 tokenizer 使用示例

这里使用一个 data point example 来展示一下 LLM 和 tokenizer 的使用示例。

下面的代码使用 instruction 和 poem 组成一个 prompt:

instruction = '以下是一首唐詩的第一句話,請用你的知識判斷並完成整首詩。'
poem = '相見時難別亦難,東風無力百花殘。'prompt = f"""\
[INST] <<SYS>>
You are a helpful assistant and good at writing Tang poem. 你是一個樂於助人的助手且擅長寫唐詩。
<</SYS>>{instruction}
{poem}
[/INST]"""

组成的 prompt 如下:

在这里插入图片描述

然后使用 tokenizer 对 prompt 做分词,得到分词后的各个 token 的 token_id:

inputs = tokenizer(prompt, return_tensors="pt")

在这里插入图片描述

tokenizer 分词的结果 inputs 包含两个字段:

  • input_ids:size 为 [batch,分词后 tokens 的个数],其中的每个元素是分词后的 token 在词表中的 token id
  • attention_mask:size 与 input_ids 一样,元素值为 0/1,1 代表这个 token 有用,0 代表无用

为了验证一下,我们将 tokenizer 分词的结果中前面几个 token id 交给 tokenizer.convert_ids_to_token() 方法来将 token ids 转为字符串,可以看到这就是 prompt 的前几个字符。

attention_mask 的用处是:当 batch 大于 1 时,每一行元素的长度值是分词后字符数量最大的,比如两行 text 做分词,一行被分为 10 个 token,一行被分为 20 个 token,那么分词后的 input_ids 和 attention_mask 的 size 为 [2, 20]attention_mask[0] 就是前 10 个元素为 1,后 10 个为 0,attention_mask[1] 就是全部为 1。

现在我们可以把 input_ids 交给 LLM 做文本生成:

model_output = model.generate(input_ids=input_ids,generation_config=generation_config,return_dict_in_generate=True,output_scores=True,max_new_tokens=max_len,
)

输出的结果也是一堆 token ids:

在这里插入图片描述

我们把这个 output 交给 tokenizer 做 decode 看一下结果:

在这里插入图片描述

7)generate_training_data 和 evaluate 函数

这里实现了两个重要的函数:

  • generate_training_data():输入一个包含 instruction、input 和 output 三个字段的 data point,将他们组成 prompt 并使用 tokenizer 分词,输出包含 input_ids 和 attention_mask 字段的 dict,这样的 dict 可以作为 transformers 库的 Trainer 用来训练 CasualLM 的样本。
  • evalute():输入 instruction、input、decoding params,输出 LLM 的响应

具体的代码实现上,就是使用上面示例的思路。代码的实现如下:

# 生成訓練資料
def generate_training_data(data_point):"""(1) Goal:- This function is used to transform a data point (input and output texts) to tokens that our model can read(2) Arguments:- data_point: dict, with field "instruction", "input", and "output" which are all str(3) Returns:- a dict with model's input tokens, attention mask that make our model causal, and corresponding output targets(3) Example:- If you construct a dict, data_point_1, with field "instruction", "input", and "output" which are all str, you can use the function like this:formulate_article(data_point_1)"""# construct full input promptprompt = f"""\
[INST] <<SYS>>
You are a helpful assistant and good at writing Tang poem. 你是一個樂於助人的助手且擅長寫唐詩。
<</SYS>>{data_point["instruction"]}
{data_point["input"]}
[/INST]"""# count the number of input tokenslen_user_prompt_tokens = (len(tokenizer(prompt,truncation=True,max_length=CUTOFF_LEN + 1,padding="max_length",)["input_ids"]) - 1)# transform input prompt into tokensfull_tokens = tokenizer(prompt + " " + data_point["output"] + "</s>",truncation=True,max_length=CUTOFF_LEN + 1,padding="max_length",)["input_ids"][:-1]return {"input_ids": full_tokens,"labels": [-100] * len_user_prompt_tokens+ full_tokens[len_user_prompt_tokens:],"attention_mask": [1] * (len(full_tokens)),}# 進行生成回覆的評估
def evaluate(instruction, generation_config, max_len, input="", verbose=True):"""(1) Goal:- This function is used to get the model's output given input strings(2) Arguments:- instruction: str, description of what you want model to do- generation_config: transformers.GenerationConfig object, to specify decoding parameters relating to model inference- max_len: int, max length of model's output- input: str, input string the model needs to solve the instruction, default is "" (no input)- verbose: bool, whether to print the mode's output, default is True(3) Returns:- output: str, the mode's response according to the instruction and the input(3) Example:- If you the instruction is "ABC" and the input is "DEF" and you want model to give an answer under 128 tokens, you can use the function like this:evaluate(instruction="ABC", generation_config=generation_config, max_len=128, input="DEF")"""# construct full input promptprompt = f"""\
[INST] <<SYS>>
You are a helpful assistant and good at writing Tang poem. 你是一個樂於助人的助手且擅長寫唐詩。
<</SYS>>{instruction}
{input}
[/INST]"""# 將提示文本轉換為模型所需的數字表示形式inputs = tokenizer(prompt, return_tensors="pt")input_ids = inputs["input_ids"].cuda()  # 分词后的所有 tokens 的 ids,size:[1, tokens长度]# 使用模型進行生成回覆generation_output = model.generate(input_ids=input_ids,generation_config=generation_config,return_dict_in_generate=True,output_scores=True,max_new_tokens=max_len,)# 將生成的回覆解碼並印出for s in generation_output.sequences:output = tokenizer.decode(s)output = output.split("[/INST]")[1].replace("</s>", "").replace("<s>", "").replace("Assistant:", "").replace("Assistant", "").strip()if (verbose):print(output)return output
8)demo examples

这里使用一些 demo examples 查看一下预训练的 LLM 在看到唐诗前两句后的输出结果:

""" It is recommmended NOT to change codes in this cell """# demo examples
test_tang_list = ['相見時難別亦難,東風無力百花殘。', '重帷深下莫愁堂,臥後清宵細細長。', '芳辰追逸趣,禁苑信多奇。']# get the model output for each examples
demo_before_finetune = []
for tang in test_tang_list:demo_before_finetune.append(f'模型輸入:\n以下是一首唐詩的第一句話,請用你的知識判斷並完成整首詩。{tang}\n\n模型輸出:\n'+evaluate('以下是一首唐詩的第一句話,請用你的知識判斷並完成整首詩。', generation_config, max_len, tang, verbose = False))# print and store the output to text file
for idx in range(len(demo_before_finetune)):print(f"Example {idx + 1}:")print(demo_before_finetune[idx])print("-" * 80)

在这里插入图片描述

9)Hyper Parameters

这里设置一些超参数。

Lab 建议修改的参数有:

num_train_data = 1040 # 設定用來訓練的資料數量,可設置的最大值為5000。在大部分情況下會希望訓練資料盡量越多越好,這會讓模型看過更多樣化的詩句,進而提升生成品質,但是也會增加訓練的時間# 使用預設參數(1040): fine-tuning大約需要25分鐘,完整跑完所有cell大約需要50分鐘# 使用最大值(5000): fine-tuning大約需要100分鐘,完整跑完所有cell大約需要120分鐘ckpt_dir = "./exp1" # 設定model checkpoint儲存目錄 (如果想要將model checkpoints存在其他目錄下可以修改這裡)
num_epoch = 1  # 設定訓練的總Epoch數 (數字越高,訓練越久,若使用免費版的colab需要注意訓練太久可能會斷線)
LEARNING_RATE = 3e-4  # 設定學習率

不建议修改的参数有(可以先不用细看):

cache_dir = "./cache"  # 設定快取目錄路徑
from_ckpt = False  # 是否從checkpoint載入模型的權重,預設為否
ckpt_name = None  # 從特定checkpoint載入權重時使用的檔案名稱,預設為無
dataset_dir = "./GenAI-Hw5/Tang_training_data.json"  # 設定資料集的目錄或檔案路徑
logging_steps = 20  # 定義訓練過程中每隔多少步驟輸出一次訓練誌
save_steps = 65  # 定義訓練過程中每隔多少步驟保存一次模型
save_total_limit = 3  # 控制最多保留幾個模型checkpoint
report_to = None  # 設定上報實驗指標的目標,預設為無
MICRO_BATCH_SIZE = 4  # 定義微批次的大小
BATCH_SIZE = 16  # 定義一個批次的大小
GRADIENT_ACCUMULATION_STEPS = BATCH_SIZE // MICRO_BATCH_SIZE  # 計算每個微批次累積的梯度步數
CUTOFF_LEN = 256  # 設定文本截斷的最大長度
LORA_R = 8  # 設定LORA(Layer-wise Random Attention)的R值
LORA_ALPHA = 16  # 設定LORA的Alpha值
LORA_DROPOUT = 0.05  # 設定LORA的Dropout率
VAL_SET_SIZE = 0  # 設定驗證集的大小,預設為無
TARGET_MODULES = ["q_proj", "up_proj", "o_proj", "k_proj", "down_proj", "gate_proj", "v_proj"] # 設定目標模組,這些模組的權重將被保存為checkpoint
device_map = "auto"  # 設定設備映射,預設為"auto"
world_size = int(os.environ.get("WORLD_SIZE", 1))  # 獲取環境變數"WORLD_SIZE"的值,若未設定則預設為1
ddp = world_size != 1  # 根據world_size判斷是否使用分散式數據處理(DDP),若world_size為1則不使用DDP
if ddp:device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)}GRADIENT_ACCUMULATION_STEPS = GRADIENT_ACCUMULATION_STEPS // world_size
10)model 的量化和 LoRA

将模型准备好,并使用 INT 8 来训练:

model = prepare_model_for_int8_training(model)

使用 LoraConfig 配置 LoRA 模型:

config = LoraConfig(r=LORA_R,lora_alpha=LORA_ALPHA,target_modules=TARGET_MODULES,lora_dropout=LORA_DROPOUT,bias="none",task_type="CAUSAL_LM",
)
model = get_peft_model(model, config)
11)加载 dataset

读取原数据集,并将所需要用到的数据写入到一个 tmp_dataset.json 文件中:

with open(dataset_dir, "r", encoding = "utf-8") as f:data_json = json.load(f)
with open("tmp_dataset.json", "w", encoding = "utf-8") as f:json.dump(data_json[:num_train_data], f, indent = 2, ensure_ascii = False)

加载为 huggingface 的 Dataset 类型:

data = load_dataset('json', data_files="tmp_dataset.json", download_mode="force_redownload")

在这里插入图片描述

按照超参数的设置,将 dataset 分为 train-set 和 valid-set:

# 將訓練數據分為訓練集和驗證集(若 VAL_SET_SIZE 大於 0)
if VAL_SET_SIZE > 0:train_val = data["train"].train_test_split(test_size=VAL_SET_SIZE, shuffle=True, seed=42)train_data = train_val["train"].shuffle().map(generate_training_data)val_data = train_val["test"].shuffle().map(generate_training_data)
else:train_data = data['train'].shuffle().map(generate_training_data)val_data = None
12)Trainer

使用 transformers 库的 Trainer 进行模型训练:

model.config.use_cachee = False# 使用 Transformers Trainer 進行模型訓練
trainer = transformers.Trainer(model=model,train_dataset=train_data,eval_dataset=val_data,args=transformers.TrainingArguments(per_device_train_batch_size=MICRO_BATCH_SIZE,gradient_accumulation_steps=GRADIENT_ACCUMULATION_STEPS,warmup_steps=50,num_train_epochs=num_epoch,learning_rate=LEARNING_RATE,fp16=True,  # 使用混合精度訓練logging_steps=logging_steps,save_strategy="steps",save_steps=save_steps,output_dir=ckpt_dir,save_total_limit=save_total_limit,ddp_find_unused_parameters=False if ddp else None,  # 是否使用 DDP,控制梯度更新策略report_to=report_to,),data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),
)
13)模型训练

使用 trainer 进行模型训练,并保存预训练结果:

trainer.train()
model.save_pretrained(ckpt_dir)
14)运行 test

前面的训练过程保存了一系列 checkpoints(ckpt),这里展示所有可用的 ckpt:

在这里插入图片描述

选择使用的 ckpt:

id_of_ckpt_to_use = -1  # 要用來進行推理的checkpoint的id(對應上一個cell的輸出結果)# 預設值-1指的是上列checkpoints中的"倒數"第一個,也就是最後一個checkpoint# 如果想要選擇其他checkpoint,可以把-1改成有列出的checkpoint id中的其中一個ckpt_name = os.path.join(ckpt_dir, ckpts[id_of_ckpt_to_use])

调整 decoding paramters:

# 你可以在這裡調整decoding parameter,decoding parameter的詳細解釋請見homework slides
max_len = 128   # 生成回復的最大長度
temperature = 0.1  # 設定生成回覆的隨機度,值越小生成的回覆越穩定
top_p = 0.3  # Top-p (nucleus) 抽樣的機率閾值,用於控制生成回覆的多樣性
# top_k = 5 # 調整Top-k值,以增加生成回覆的多樣性和避免生成重複的詞彙

从指定的 checkpoint 加载模型权重:

test_data_path = "GenAI-Hw5/Tang_testing_data.json"
output_dir = "./output"  # 設定作業結果輸出目錄 (如果想要把作業結果存在其他目錄底下可以修改這裡,強烈建議存在預設值的子目錄下,也就是Google Drive裡)
output_path = os.path.join(output_dir, "results.txt")cache_dir = "/root/autodl-tmp/cache/hub"  # 設定快取目錄路徑
seed = 42  # 設定隨機種子,用於重現結果
no_repeat_ngram_size = 3  # 設定禁止重複 Ngram 的大小,用於避免生成重複片段nf4_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_use_double_quant=True,bnb_4bit_compute_dtype=torch.bfloat16
)# 使用 tokenizer 將模型名稱轉換成模型可讀的數字表示形式
tokenizer = AutoTokenizer.from_pretrained(model_name,cache_dir=cache_dir,quantization_config=nf4_config
)# 從預訓練模型載入模型並設定為 8 位整數 (INT8) 模型
model = AutoModelForCausalLM.from_pretrained(model_name,quantization_config=nf4_config,device_map={'': 0},  # 設定使用的設備,此處指定為 GPU 0cache_dir=cache_dir
)# 從指定的 checkpoint 載入模型權重
model = PeftModel.from_pretrained(model, ckpt_name, device_map={'': 0})

运行 test dataset:

results = []# 設定生成配置,包括隨機度、束搜索等相關參數
generation_config = GenerationConfig(do_sample=True,temperature=temperature,num_beams=1,top_p=top_p,# top_k=top_k,no_repeat_ngram_size=no_repeat_ngram_size,pad_token_id=2
)# 讀取測試資料
with open(test_data_path, "r", encoding = "utf-8") as f:test_datas = json.load(f)# 對於每個測試資料進行預測,並存下結果
with open(output_path, "w", encoding = "utf-8") as f:for (i, test_data) in enumerate(test_datas):predict = evaluate(test_data["instruction"], generation_config, max_len, test_data["input"], verbose = False)f.write(f"{i+1}. "+test_data["input"]+predict+"\n")print(f"{i+1}. "+test_data["input"]+predict)

打印出的测试结果:

在这里插入图片描述
(很多还是很搞笑的)

5. 总结

以上代码展示了如何加载一个 LLM 并对其针对 specific task 做 fine tune,通过修改相应的 dataset 可以复用相关代码实现其他的特定任务微调。整个代码值得学习。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tcp协议的延迟应答(介绍+原则),拥塞控制(拥塞窗口,网络出现拥塞时,滑动窗口的大小如何确定,慢启动,阈值)

目录 延迟应答 引入 介绍 原则 拥塞控制 引入 网络出现拥塞 引入 介绍 介绍 拥塞窗口 介绍 决定滑动窗口的大小 慢启动 介绍 为什么要有慢启动 阈值 算法 总结 延迟应答 引入 发送方一次发送更多的数据,发送效率就越高 因为要写入网卡硬件的io速度很慢,尽量…

conda 创建环境失败

conda create -n pylableimg python3.10在conda &#xff08;base&#xff09;环境下&#xff0c;创建新的环境&#xff0c;失败。 报错&#xff1a; LookupError: didn’t find info-scipy-1.11.3-py310h309d312_0 component in C:\Users\Jane.conda\pkgs\scipy-1.11.3-py310h…

英伟达:史上最牛一笔天使投资

200万美元的天使投资&#xff0c;让刚成立就面临倒闭风险的英伟达由危转安&#xff0c;并由此缔造了一个2.8万亿美元的市值神话。 这是全球风投史上浓墨重彩的一笔。 前不久&#xff0c;黄仁勋在母校斯坦福大学的演讲中&#xff0c;提到了人生中的第一笔融资——1993年&#x…

刷代码随想录有感(98):动态规划——爬楼梯

题干&#xff1a; 代码&#xff1a; class Solution { public:int climbStairs(int n) {if(n 1)return 1;if(n 2)return 2;vector<int>dp(n 1);dp[0] 0;dp[1] 1;dp[2] 2;for(int i 3; i < n; i){dp[i] dp[i - 1] dp[i - 2];}return dp[n];} }; 其实就是斐波…

liquibase做数据库版本管理

通过这个配置就会自动启动liquibase 比对 https://www.cnblogs.com/ludangxin/p/16676701.html https://zhuyizhuo.github.io/2020/07/04/spring-boot/spring-boot-liquibase-database-version-control/

上市公司短视主义数据集(2001-2022年)

数据简介&#xff1a;上市公司短视主义是指公司管理层过于关注短期业绩和股价表现&#xff0c;而忽视公司的长期发展和战略规划。这种短视行为可能会导致公司投资决策的失误&#xff0c;影响公司的长期竞争力。 在上市公司年度报告年度中&#xff0c;通过已有的反映管理者“短…

Excel 将同一分类下的值依次填进分类格右边的格中

表格的第2列是分类&#xff0c;第3列是明细&#xff1a; ABC1S.noAccountProduct21AAAQatAAG32BAAQbIAAW43BAAQkJAAW54CAAQaAAP65DAAQaAAX76DAAQbAAX87DAAQcAAX 需要将同一分类下的值依次填入分类格右边的格中&#xff1a; ABCD1S.noAccountProduct21AAAQatAAG32BAAQbIAAWkJ…

快速安装Windows和Ubuntu双系统

一、参考资料 用UltraISO制作Ubuntu16.04 U盘启动盘 DiskPart Command-Line Options 二、相关介绍 1. MBR和GPT分区模式 MBR分区模式 MBR最大仅支持2TB磁盘&#xff0c;超过2TB不可识别。 MBR&#xff08;Master Boot Record&#xff09;&#xff0c;即硬盘的主引导记录分…

【激光雷达】

激光雷达 机械式360扫描雷达半固态激光雷达二维扫描一维扫描 固态激光雷达OPA固态激光雷达&#xff08; 光学相控阵技术&#xff09; FMCW 激光雷达 激光雷达技术在近几年可以说是蓬勃发展&#xff0c;新能源汽车的大量使用&#xff0c;给雷达技术的发展提供了肥沃的土壤&#…

嵌入式作业6

1、利用SysTick定时器编写倒计时程序&#xff0c;如初始设置为2分30秒&#xff0c;每秒在屏幕上输出一次时间&#xff0c;倒计时为0后&#xff0c;红灯亮&#xff0c;停止屏幕输出&#xff0c;并关闭SysTick定时器的中断。 2、利用RTC显示日期&#xff08;年月日、时分秒&…

【C++类和对象中篇】(构造函数和析构函数)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f369;1.默认成员函数的概念&#xff1a; &#x1f369;2.构造函数&#xff1a; 2.1特性&…

从零开始理解AdaBoost算法:设计思路与算法流程(二)【权值更新与加权表决、数学公式】

设计思路 AdaBoost算法属于Boosting算法家族中的一种&#xff0c;其基本思路是将多个弱分类器组合成一个强分类器。 “强分类器”是指一个分类准确率较高的模型“弱分类器”则是指分类准确率略高于随机猜测的简单模型。 AdaBoost的核心思想是通过 加权 的方式逐步提高分类器…

黑马es学习

es 0. 基础概念0.1 倒排索引0.2 文档、索引0.3 与mysql对比 1 基本操作1.1 mapping 索引库操作1.2 单个文档CRUD 3. DSL查询3.1 查询所有3.2 全文检索3.3 精确查询3.4 复合查询-相关性得分3.5 分页3.6 高亮3.7 总结 2. RestClientmysql与es数据同步es集群去重 黑马视频 官方使…

Docker:利用Docker搭建一个nginx服务

文章目录 搭建一个nginx服务认识nginx服务Web服务器反向代理服务器高性能特点 安装nginx启动nginx停止nginx查找nginx镜像拉取nginx镜像&#xff0c;启动nginx站点其他方式拉取nginx镜像信息通过 DIGEST 拉取镜像 搭建一个nginx服务 首先先认识一下nginx服务&#xff1a; NGI…

04-认识微服务-SpringCloud

04-认识微服务-SpringCloud 1.SpringCloud&#xff1a; 1.SpringCloud是目前国内使用最广泛的微服务框架。官网地址&#xff1a;https://spring.io/projects/spring-cloud 2.SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&…

SpringCloud-面试篇(二十四)

&#xff08;1&#xff09;Nacos如何支撑数十万服务注册的压力 小型企业来讲nacos压力没有那么大&#xff0c;但是想阿里&#xff0c;服务的数量可能会达到数万&#xff0c;那麽多的服务。当服务原来越多时&#xff0c;除了服务注册以外&#xff0c;还有服务的定时更新&#x…

自养号测评防关联的关键点解析, 确保店铺权重和买家账号的安全稳定

现在很多大卖都是自己管理几百个账号&#xff0c;交给服务商不是特别靠谱。你不知道服务商账号质量怎么样&#xff0c;账号一天下了多少你也不清楚&#xff0c;如果下了很多单万一封号被关联了怎么办&#xff0c;你也不知道服务商用什么卡给你下单&#xff0c;用一些低汇率和黑…

一个简单好用的 C# Easing Animation 缓动动画类库

文章目录 1.类库说明2.使用步骤2.1 创建一个Windows Form 项目2.2 安装类库2.3 编码2.4 效果 3. 扩展方法3.1 MoveTo 动画3.2 使用回调函数的Color动画3.3 属性动画3.4 自定义缓动函数 4.该库支持的内置缓动函数5.代码下载 1.类库说明 App.Animations 类库是一个很精炼、好用的…

Django ORM的QuerySet:解锁数据库交互的魔法钥匙

用到此篇文章知识的几篇文章&#xff1a; Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django API开发实战&#xff1a;前后端分离、Restful风格与DRF序列化器详解 文章目录 前言一、什么是QuerySet&#xff1f;二、QuerySet 的用途三…

Dell服务器根据GPU温度调整风扇转速

前言 dell服务器自动风扇是根据CPU温度来调速的&#xff0c;我跑AI的时候cpu温度不高但是GPU温度很高导致显卡卡死PVE虚拟机直接挂起无法运行&#xff0c;我看了下也没有基于显卡温度调速的脚本&#xff0c;于是我就自己写了一个 基于ipmi工具 乌班图等linux先安装ipmi apt …