Lora微LLAMA模型實戰

引言

本文介紹如何復現Alpaca-lora,即基于alpaca數據集用lora方法微調Llama模型。

環境準備

實驗環境用的是lanyun,新用戶點擊注冊可以送算力。

下載huggingface上的模型是一個令人頭疼的問題,但在lanyun上可以通過在終端運行source /etc/network_turbo 配置加速下載 :

image-20250316145517497

如上圖,速度還是很快的。

如果不是lanyun上可以嘗試:export HF_ENDPOINT=https://hf-mirror.com ,但可能不太穩定。

Cuda版本、pytorch版本如下:

image-20250316145636288

安裝依賴

將下面的內容復制到requirements.txt中:

accelerate
appdirs
loralib
bitsandbytes
black
black[jupyter]
datasets
fire
peft
transformers>=4.28.0
sentencepiece
gradio

比如我這里復制到 /root/lanyun-tmp/目錄下。然后依次執行:

source /etc/network_turbo 
pip install -r requirements.txt

其輸出可能為:

Collecting appdirs (from -r requirements.txt (line 2))
...
Successfully installed aiofiles-23.2.1 aiohappyeyeballs-2.6.1 aiohttp-3.11.13 aiosignal-1.3.2 annotated-types-0.7.0 appdirs-1.4.4 async-timeout-5.0.1 bitsandbytes-0.45.3 black-25.1.0 click-8.1.8 datasets-3.4.0 dill-0.3.8 fastapi-0.115.11 ffmpy-0.5.0 fire-0.7.0 frozenlist-1.5.0 gradio-5.21.0 gradio-client-1.7.2 groovy-0.1.2 loralib-0.1.2 markdown-it-py-3.0.0 mdurl-0.1.2 multidict-6.1.0 multiprocess-0.70.16 mypy-extensions-1.0.0 orjson-3.10.15 pandas-2.2.3 pathspec-0.12.1 peft-0.14.0 propcache-0.3.0 pyarrow-19.0.1 pydantic-2.10.6 pydantic-core-2.27.2 pydub-0.25.1 python-multipart-0.0.20 pytz-2025.1 requests-2.32.3 rich-13.9.4 ruff-0.11.0 safehttpx-0.1.6 semantic-version-2.10.0 sentencepiece-0.2.0 shellingham-1.5.4 starlette-0.46.1 termcolor-2.5.0 tokenize-rt-6.1.0 tomlkit-0.13.2 tqdm-4.67.1 typer-0.15.2 tzdata-2025.1 uvicorn-0.34.0 websockets-15.0.1 xxhash-3.5.0 yarl-1.18.3

等待依賴下載完畢。

模型格式轉換

首先需要將LLaMA原始權重文件轉換為Transformers庫對應的模型文件格式,但我們也可以選擇別人轉換好的,比如 https://huggingface.co/dfurman/LLaMA-7B:

LLaMA-7B is a base model for text generation with 6.7B parameters and a 1T token training corpus. It was built and released by the FAIR team at Meta AI alongside the paper "LLaMA: Open and Efficient Foundation Language Models".This model repo was converted to work with the transformers package. It is under a bespoke non-commercial license, please see the LICENSE file for more details.

下面編寫代碼下載模型:

download_model.py:

import transformers
import torchmodel_name = "dfurman/llama-7b"tokenizer = transformers.AutoTokenizer.from_pretrained(model_name)
streamer = transformers.TextStreamer(tokenizer)model = transformers.LlamaForCausalLM.from_pretrained(model_name,torch_dtype=torch.bfloat16,device_map="auto"
)

等待執行完畢我們就下載好了想要的模型格式。

訓練

單卡訓練

克隆alpaca-lora項目的源碼:

git clone https://github.com/tloen/alpaca-lora.git
cd alpaca-lora

修改alpaca-lora目錄下的 finetune.py文件,將prepare_model_for_int8_training替換為prepare_model_for_kbit_training,不然新版(0.14.0)的peft會報錯。

然后在該目錄下執行:

python finetune.py \--base_model 'dfurman/llama-7b' \--data_path 'yahma/alpaca-cleaned' \--output_dir './lora-alpaca'

這里的dfurman/llama-7b是我們剛才下載好的模型;yahma/alpaca-cleaned,參考4項目任務原始的alpaca數據集質量不高,因此他們對該數據集進行了一個清理,得到了更高質量的alpaca-cleaned

Training Alpaca-LoRA model with params:
base_model: dfurman/llama-7b
data_path: yahma/alpaca-cleaned
output_dir: ./lora-alpaca
batch_size: 128
micro_batch_size: 4
num_epochs: 3
learning_rate: 0.0003
cutoff_len: 256
val_set_size: 2000
lora_r: 8
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules: ['q_proj', 'v_proj']
train_on_inputs: True
add_eos_token: False
group_by_length: False
wandb_project: 
wandb_run_name: 
wandb_watch: 
wandb_log_model: 
resume_from_checkpoint: False
prompt template: alpaca
...                                                                                   | 5/1164 [01:49<6:57:53, 21.63s/it]

從上面可以看到一些默認的參數配置,但是需要訓練7個小時左右,太慢了。finetune.py的代碼是支持單機多卡的,因此我們重新創建一個4卡的實例。

多卡訓練

下面來一步一步在Lanyun上操作一下:

image-20250316160428548

image-20250316160520634

這里我們選擇了4卡,并且選擇好了Cuda等版本。

等待創建完畢后:

image-20250316160646272

點擊JupyterLab進入代碼環境。

image-20250316160729009

進入后我們可以看到這樣的解碼,這里直接點擊Terminal進入終端環境。

第一步執行:

source /etc/network_turbo 

第二步克隆項目:

git clone https://github.com/tloen/alpaca-lora.git
cd alpaca-lora

第三步安裝依賴:

pip install -r requirements.txt

第四步修改alpaca-lora目錄下的 finetune.py文件,將prepare_model_for_int8_training替換為prepare_model_for_kbit_training,主要修改有兩處。

第五步利用數據并行,在4卡上進行訓練:

nohup torchrun --nproc_per_node=4 --master_port=29005 finetune.py \--base_model 'dfurman/llama-7b' \--data_path 'yahma/alpaca-cleaned' \--num_epochs=10 \--cutoff_len=512 \--group_by_length \--output_dir='./lora-alpaca' \--lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \--lora_r=16 \--micro_batch_size=8 > output.log 2>&1 &

同時這里參考 https://huggingface.co/tloen/alpaca-lora-7b 上的例子調整下參數。

[2025-03-16 16:18:21,847] torch.distributed.run: [WARNING] 
[2025-03-16 16:18:21,847] torch.distributed.run: [WARNING] *****************************************
[2025-03-16 16:18:21,847] torch.distributed.run: [WARNING] Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. 
[2025-03-16 16:18:21,847] torch.distributed.run: [WARNING] *****************************************
Training Alpaca-LoRA model with params:
base_model: dfurman/llama-7b
data_path: yahma/alpaca-cleaned
output_dir: ./lora-alpaca
batch_size: 128
micro_batch_size: 8
num_epochs: 10
learning_rate: 0.0003
cutoff_len: 512
val_set_size: 2000
lora_r: 16
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules: ['q_proj', 'k_proj', 'v_proj', 'o_proj']
train_on_inputs: True
add_eos_token: False
group_by_length: True
wandb_project: 
wandb_run_name: 
wandb_watch: 
wandb_log_model: 
resume_from_checkpoint: False
prompt template: alpaca
...

這次會自動從huggingface上下載模型dfurman/llama-7b并開始單機多卡訓練。

 trainable params: 16,777,216 || all params: 6,755,192,832 || trainable%: 0.24840%|▌                                                                                  4/3880 [00:30<6:16:57,  7.08s/it]

image-20250316164020138

顯存使用如上,每個卡都用了16.8G。

4卡訓練了5個小時左右,終于訓練好了。

推理

在倉庫根目錄下執行:

python generate.py     --load_8bit     --base_model 'dfurman/llama-7b'     --lora_weights 'lora-alpaca'
AttributeError: module 'gradio' has no attribute 'inputs'

遇到了上面的錯誤,這是因為倉庫的代碼有點老,一種比較簡單的方法是降低版本:

pip install gradio==3.43.1
Running on local URL:  http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
IMPORTANT: You are using gradio version 3.43.1, however version 4.44.1 is available, please upgrade.
--------

頂著各種警告,終于跑起來了。

但是我們在Lanyun上無法訪問這個端口,如果是個人電腦可以直接打開了。要在Lanyun上訪問,需要通過端口映射開放端口:

image-20250317180326312

找到generate.py中195行這句代碼,添加指定的server_port

    ).queue().launch(server_name="0.0.0.0", share=share_gradio, server_port=17860)

image-20250317181738506

啟動成功后點擊端口映射中的訪問即可:

image-20250317181825796

finetune.py文件分析

該項目下的finetune.py腳本值得我們學習一下:

import os
import sys
from typing import Listimport fire
import torch
import transformers
from datasets import load_dataset"""
Unused imports:
import torch.nn as nn
import bitsandbytes as bnb
"""from peft import (LoraConfig,get_peft_model,get_peft_model_state_dict,prepare_model_for_int8_training,set_peft_model_state_dict,
)
from transformers import LlamaForCausalLM, LlamaTokenizer
# 自定義的提示詞工具
from utils.prompter import Prompterdef train(# model/data paramsbase_model: str = "",  # the only required argumentdata_path: str = "yahma/alpaca-cleaned", # 會從huggingface上去下載output_dir: str = "./lora-alpaca", # 訓練超參batch_size: int = 128, # 梯度累積后的批大小micro_batch_size: int = 4, # 實際的批大小num_epochs: int = 3, # 訓練輪次learning_rate: float = 3e-4, cutoff_len: int = 256, # 最長長度val_set_size: int = 2000, # 驗證集大小# lora 超參lora_r: int = 8, # 低秩矩陣的維度lora_alpha: int = 16, # 低秩矩陣的比例因子lora_dropout: float = 0.05, # LoRA層的dropout概率# 應用lora到 query 和 value的投影層(Linear層)lora_target_modules: List[str] = ["q_proj","v_proj",],# llm 超參train_on_inputs: bool = True,  # if False, masks out inputs in lossadd_eos_token: bool = False,group_by_length: bool = False,  # faster, but produces an odd training loss curve# wandb log 相關參數wandb_project: str = "",wandb_run_name: str = "",wandb_watch: str = "",  # options: false | gradients | allwandb_log_model: str = "",  # options: false | trueresume_from_checkpoint: str = None,  # either training checkpoint or final adapterprompt_template_name: str = "alpaca",  # The prompt template to use, will default to alpaca.
):if int(os.environ.get("LOCAL_RANK", 0)) == 0:print(f"Training Alpaca-LoRA model with params:\n"f"base_model: {base_model}\n"f"data_path: {data_path}\n"f"output_dir: {output_dir}\n"f"batch_size: {batch_size}\n"f"micro_batch_size: {micro_batch_size}\n"f"num_epochs: {num_epochs}\n"f"learning_rate: {learning_rate}\n"f"cutoff_len: {cutoff_len}\n"f"val_set_size: {val_set_size}\n"f"lora_r: {lora_r}\n"f"lora_alpha: {lora_alpha}\n"f"lora_dropout: {lora_dropout}\n"f"lora_target_modules: {lora_target_modules}\n"f"train_on_inputs: {train_on_inputs}\n"f"add_eos_token: {add_eos_token}\n"f"group_by_length: {group_by_length}\n"f"wandb_project: {wandb_project}\n"f"wandb_run_name: {wandb_run_name}\n"f"wandb_watch: {wandb_watch}\n"f"wandb_log_model: {wandb_log_model}\n"f"resume_from_checkpoint: {resume_from_checkpoint or False}\n"f"prompt template: {prompt_template_name}\n")assert (base_model), "Please specify a --base_model, e.g. --base_model='huggyllama/llama-7b'"#gradient_accumulation_steps = batch_size // micro_batch_size# 自定義了提示詞工具類prompter = Prompter(prompt_template_name)device_map = "auto"# 分布式訓練時指定的設備數量world_size = int(os.environ.get("WORLD_SIZE", 1))# 判斷是否為分布式訓練ddp = world_size != 1if ddp:device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)}gradient_accumulation_steps = gradient_accumulation_steps // world_sizeuse_wandb = len(wandb_project) > 0 or ("WANDB_PROJECT" in os.environ and len(os.environ["WANDB_PROJECT"]) > 0)if len(wandb_project) > 0:os.environ["WANDB_PROJECT"] = wandb_projectif len(wandb_watch) > 0:os.environ["WANDB_WATCH"] = wandb_watchif len(wandb_log_model) > 0:os.environ["WANDB_LOG_MODEL"] = wandb_log_model# 使用transformers 加載Llama模型model = LlamaForCausalLM.from_pretrained(base_model,load_in_8bit=True,torch_dtype=torch.float16,device_map=device_map,)# 加載分詞器tokenizer = LlamaTokenizer.from_pretrained(base_model)tokenizer.pad_token_id = (0  # unk. we want this to be different from the eos token)tokenizer.padding_side = "left"  # Allow batched inferencedef tokenize(prompt, add_eos_token=True):# there's probably a way to do this with the tokenizer settings# but again, gotta move fastresult = tokenizer(prompt,truncation=True,max_length=cutoff_len,padding=False,return_tensors=None,)if (result["input_ids"][-1] != tokenizer.eos_token_idand len(result["input_ids"]) < cutoff_lenand add_eos_token):result["input_ids"].append(tokenizer.eos_token_id)result["attention_mask"].append(1)result["labels"] = result["input_ids"].copy()return resultdef generate_and_tokenize_prompt(data_point):# 得到輸入提示詞full_prompt = prompter.generate_prompt(data_point["instruction"],data_point["input"],data_point["output"],)tokenized_full_prompt = tokenize(full_prompt)if not train_on_inputs:user_prompt = prompter.generate_prompt(data_point["instruction"], data_point["input"])tokenized_user_prompt = tokenize(user_prompt, add_eos_token=add_eos_token)user_prompt_len = len(tokenized_user_prompt["input_ids"])if add_eos_token:user_prompt_len -= 1tokenized_full_prompt["labels"] = [-100] * user_prompt_len + tokenized_full_prompt["labels"][user_prompt_len:]  # could be sped up, probablyreturn tokenized_full_prompt#  適配 INT8 訓練,減少顯存占用model = prepare_model_for_int8_training(model)# Lora配置config = LoraConfig(r=lora_r,lora_alpha=lora_alpha,target_modules=lora_target_modules,lora_dropout=lora_dropout,bias="none", task_type="CAUSAL_LM", # 任務類型為因果語言模型)# model = get_peft_model(model, config)if data_path.endswith(".json") or data_path.endswith(".jsonl"):data = load_dataset("json", data_files=data_path)else:data = load_dataset(data_path)# 從斷點恢復if resume_from_checkpoint:# Check the available weights and load themcheckpoint_name = os.path.join(resume_from_checkpoint, "pytorch_model.bin")  # Full checkpointif not os.path.exists(checkpoint_name):checkpoint_name = os.path.join(resume_from_checkpoint, "adapter_model.bin")  # only LoRA model - LoRA config above has to fitresume_from_checkpoint = (False  # So the trainer won't try loading its state)# The two files above have a different name depending on how they were saved, but are actually the same.if os.path.exists(checkpoint_name):print(f"Restarting from {checkpoint_name}")adapters_weights = torch.load(checkpoint_name)set_peft_model_state_dict(model, adapters_weights)else:print(f"Checkpoint {checkpoint_name} not found")model.print_trainable_parameters()  # Be more transparent about the % of trainable params.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_and_tokenize_prompt))val_data = (train_val["test"].shuffle().map(generate_and_tokenize_prompt))else:train_data = data["train"].shuffle().map(generate_and_tokenize_prompt)val_data = Noneif not ddp and torch.cuda.device_count() > 1:# keeps Trainer from trying its own DataParallelism when more than 1 gpu is availablemodel.is_parallelizable = Truemodel.model_parallel = Truetrainer = 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=100,num_train_epochs=num_epochs,learning_rate=learning_rate,fp16=True,logging_steps=10,optim="adamw_torch",evaluation_strategy="steps" if val_set_size > 0 else "no",save_strategy="steps",eval_steps=200 if val_set_size > 0 else None,save_steps=200,output_dir=output_dir,save_total_limit=3,load_best_model_at_end=True if val_set_size > 0 else False,ddp_find_unused_parameters=False if ddp else None,group_by_length=group_by_length,report_to="wandb" if use_wandb else None,run_name=wandb_run_name if use_wandb else None,),data_collator=transformers.DataCollatorForSeq2Seq(tokenizer, pad_to_multiple_of=8, return_tensors="pt", padding=True), # pad_to_multiple_of = 8 對齊到 8 的倍數)model.config.use_cache = Falseold_state_dict = model.state_dictmodel.state_dict = (lambda self, *_, **__: get_peft_model_state_dict(self, old_state_dict())).__get__(model, type(model))if torch.__version__ >= "2" and sys.platform != "win32":# 加速模型推理和訓練model = torch.compile(model)trainer.train(resume_from_checkpoint=resume_from_checkpoint)model.save_pretrained(output_dir)print("\n If there's a warning about missing keys above, please disregard :)")if __name__ == "__main__":fire.Fire(train)

參考

  1. https://huggingface.co/dfurman/LLaMA-7B
  2. https://github.com/tloen/alpaca-lora
  3. https://zhuanlan.zhihu.com/p/619426866
  4. https://github.com/gururise/AlpacaDataCleaned

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73766.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73766.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73766.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Maven常見問題匯總

Maven刷新,本地倉庫無法更新 現象 This failure was cached in the local repository and resolution is not reattempted until the update interval of aliyunmaven has elapsed or updates are forced原因 因為上一次嘗試下載&#xff0c;發現對應的倉庫沒有這個maven配置…

什么是站群服務器?站群服務器應該怎么選?

站群服務器是專門用于托管和管理多個網站的服務器。通常用于SEO優化、內容分發、廣告推廣等場景&#xff0c;用戶可以通過一個服務器管理多個站點&#xff0c;提升效率并降低成本。選擇站群服務器時&#xff0c;需根據業務需求、性能要求、IP資源等因素進行綜合考慮。 什么是站…

分享一個項目中遇到的一個算法題

需求背景&#xff1a; 需求是用戶要創建一個任務計劃在未來執行&#xff0c;要求在創建任務計劃的時候判斷選擇的時間是否符合要求&#xff0c;否則不允許創建&#xff0c;創建的任務類型有兩種&#xff0c;一種是單次&#xff0c;任務只執行一次&#xff1b;另一種是周期&…

【LInux進程六】命令行參數和環境變量

【LInux進程六】命令行參數和環境變量 1.main函數的兩個參數2.利用main函數實現一個簡單的計算器3.環境變量之一&#xff1a;PATH4.修改PATH5.在命令行解釋器bash中查看所有環境變量6.用自己寫的程序查看環境變量7.main函數的第三個參數8.本地的環境變量和環境變量9.環境變量具…

時間軸版本-2.0

文章簡述 這是本人自己封裝的時間軸2.0版本的代碼&#xff0c;用到了TypeScriptJavaScript 這篇文章只有代碼和具體的使用方式&#xff0c;如果想看具體的講解可以參考本人寫的時間軸1.0版本的&#xff0c;在1.0版本中可能計算時間線的邏輯略有不同&#xff0c;但是大致的計算…

大語言模型的壓縮技術

盡管人們對越來越大的語言模型一直很感興趣&#xff0c;但MistralAI 向我們表明&#xff0c;規模只是相對而言的&#xff0c;而對邊緣計算日益增長的興趣促使我們使用小型語言獲得不錯的結果。壓縮技術提供了一種替代方法。在本文中&#xff0c;我將解釋這些技術&#xff0c;并…

大華HTTP協議在智聯視頻超融合平臺中的接入方法

一. 大華HTTP協議介紹 大華HTTP協議是大華股份&#xff08;Dahua Technology&#xff09;為其安防監控設備開發的一套基于HTTP/HTTPS的通信協議&#xff0c;主要用于設備與客戶端&#xff08;如PC、手機、服務器&#xff09;之間的數據交互。該協議支持設備管理、視頻流獲取、…

Linux內核實時機制28 - RT調度器11 - RT 組調度

Linux內核實時機制28 - RT調度器11 - RT 組調度 相關數據結構 內核中通過static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)函數來判斷實時任務運行時間是否超出帶寬限制,判斷這個運行隊列rt_rq的運行時間是否超過了額定的運行時間。而“運行時間”和“額定時間”都…

java,poi,提取ppt文件中的文字內容

注意&#xff0c;不涉及圖片處理。 先上pom依賴&#xff1a; <!-- 處理PPTX文件 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><!--…

7、vue3做了什么

大佬認為有何優點&#xff1a; 組合式api----邏輯集中、對ts有更好的支持RFC–開放了一個討論機制&#xff0c;可以看到每一個api的提案&#xff0c;方便源碼維護&#xff0c;功能擴展&#xff0c;大家一起討論 官方rfc響應式獨立&#xff0c;new Proxy&#xff0c;天生自帶來…

多人在線聊天系統,創建群,視頻,語音,自帶帶授權碼

多人在線聊天系統&#xff0c;創建群&#xff0c;視頻&#xff0c;語音 帶授權碼&#xff0c;授權碼限制 10 個網站&#xff0c;需要下載研究吧 在線聊天&#xff0c;創建群&#xff0c;表情&#xff0c;圖片&#xff0c;文件&#xff0c;視頻&#xff0c;語音&#xff0c;自…

數據結構概覽

關鍵點&#xff1a; 數據結構是組織和存儲數據的方式&#xff0c;幫助高效訪問和操作數據。常見類型包括數組、鏈表、棧、隊列、樹和圖&#xff0c;每種都有特定用途。代碼示例和實際應用場景將幫助初學者理解這些概念。 什么是數據結構&#xff1f; 數據結構就像你整理書架或…

Android studio點擊運行按鈕在build\intermediates\apk\debug目錄下生成的apk在真機上安裝失敗,提示test only

Android studio點擊運行按鈕在build\intermediates\apk\debug目錄下生成的apk在真機上安裝失敗&#xff0c;提示test only DeepSeek R1 思考 15 秒 思考過程 針對Android Studio生成的APK在真機安裝時提示“test only”的問題&#xff0c;以下是詳細解決方案&#xff1a; 1.…

NFC 碰一碰發視頻源碼搭建,支持OEM

一、引言 NFC&#xff08;Near Field Communication&#xff09;近場通信技術&#xff0c;以其便捷、快速的數據交互特性&#xff0c;正廣泛應用于各個領域。其中&#xff0c;NFC 碰一碰發視頻這一應用場景&#xff0c;為用戶帶來了新穎且高效的視頻分享體驗。想象一下&#x…

Python基礎語法全解析:從入門到實踐

Python作為一門簡潔高效、功能強大的編程語言&#xff0c;憑借其易讀性和豐富的生態系統&#xff0c;已成為編程領域的“明星語言”。本文將系統講解Python的核心語法&#xff0c;涵蓋變量、數據類型、控制結構、函數、模塊等核心概念&#xff0c;幫助讀者快速掌握編程基礎。 一…

TypeScript中的類型斷言(type assertion),如何使用類型斷言進行類型轉換?

一、什么是類型斷言&#xff1f; 類型斷言&#xff08;Type Assertion&#xff09;是 TypeScript 中一種顯式指定變量類型的方式&#xff0c;它告訴編譯器&#xff1a;“我比編譯器更清楚這個值的類型”。?這不是運行時類型轉換&#xff0c;而是編譯階段的類型聲明輔助機制。…

分區表和分表

分區表&#xff08;Partitioning&#xff09; 定義 分區表是將單個表的數據按照某種規則&#xff08;如范圍、列表、哈希等&#xff09;劃分為多個邏輯部分&#xff0c;每個部分稱為一個分區。數據仍然存儲在一個物理表中&#xff0c;但邏輯上被分割為多個分區。 特點 邏輯…

C++從入門到入土(八)——多態的原理

目錄 前言 多態的原理 動態綁定與靜態綁定 虛函數表 小結 前言 在前面的文章中&#xff0c;我們介紹了C三大特性之一的多態&#xff0c;我們主要介紹了多態的構成條件&#xff0c;但是對于多態的原理我們探討的是不夠深入的&#xff0c;下面這這一篇文章&#xff0c;我們將…

用Maven創建只有POM文件的項目

使用 mvn 創建一個僅包含 pom.xml 文件的父項目&#xff0c;可以借助 maven-archetype-quickstart 原型&#xff0c;然后移除不必要的文件&#xff0c;或者直接通過命令生成最簡的 pom.xml 文件。以下是具體操作步驟&#xff1a; 一、方法一&#xff1a;使用原型創建后清理 1…

Linux目錄理解

前言 最近在復習linux&#xff0c;發現有些目錄總是忘記內容&#xff0c;發現有些還是得從原義和實際例子去理解會記憶深刻些。以下是個人的一些理解 Linux目錄 常見的Linux下的目錄如下&#xff1a; 1. 根目錄 / (Root Directory) 英文含義&#xff1a;/ 是文件系統的根…