目录

1.1 蒸馏目标

2 环境准备

2.1依赖库安装

2.2 硬件要求

2.3 模型与数据集下载

2.3.1 教师模型下载

2.3.2 学生模型下载

 2.3.3 数据集准备或下载

 3.过程日志

 4. 模型加载与配置

4.1 加载教师模型

4.2 加载学生模型

4.3 数据预处理函数  

 4.4 数据收集器

4.5 定义训练参数

4.6 定义蒸馏配置

4.7 定义训练配置

4.8 创建蒸馏器 

4.9 开始蒸馏 

 5. 完整代码

6.结合上述内容和TextBrewer,自己重新整理了一遍代码,仅供参考:

1.1 蒸馏目标

将 DeepSeek 的推理能力迁移到 Qwen-2.5;

确保学生模型与 Qwen-2.5 的原始功能(如对话、多语言支持)兼容。

2 环境准备

2.1依赖库安装

pip install torch torchvision transformers datasets2.2
pip install accelerate # 加速分布式训练
pip install evaluate # 评估指标

2.2 硬件要求

GPU:建议使用单张或多张 NVIDIA GPU(如 V100、A100)建议至少 24GB。

CUDA:安装与 PyTorch 兼容的 CUDA 版本。

2.3 模型与数据集下载

2.3.1 教师模型下载

Qwen-2.5-1.5B从huggingface 下载,离线下载方式(从https://hf-mirror.com离线下载):

$env:HF_ENDPOINT = "https://hf-mirror.com"huggingface-cli download Qwen/Qwen2.5-1.5B --local-dir ./models/qwen2.5-1.5B --local-dir-use-symlinks False

2.3.2 学生模型下载

Qwen-2.5-1.5B

$env:HF_ENDPOINT = "https://hf-mirror.com"huggingface-cli download Qwen/Qwen2.5-1.5B --local-dir ./models/qwen2.5-1.5B --local-dir-use-symlinks False

 2.3.3 数据集准备或下载

建议使用大规模文本数据集(如 wikitex、Wikipedia、BooksCorpus、OpenWebText 等)。离线下载地址(从https://www.kaggle.com/datasets/jayanthbontha/wikitext下载)

 3.过程日志

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)# 获取当前脚本文件的绝对路径
current_script_path = os.path.abspath(__file__)
logger.info(f"Current script path: {current_script_path}")# 获取当前脚本文件所在的目录
current_script_dir = os.path.dirname(current_script_path)
logger.info(f"Current script directory: {current_script_dir}")

 4. 模型加载与配置

4.1 加载教师模型

# 加载教师模型(DeepSeek-R1:1.5B)
teacher_model_name = os.path.join(current_script_dir, "../models/DeepSeek-R1-Distill-Qwen-1.5B")
logger.info(f"Loading teacher model: {teacher_model_name}")
teacher_tokenizer = AutoTokenizer.from_pretrained(teacher_model_name,local_files_only=True
)
teacher_model = AutoModelForCausalLM.from_pretrained(teacher_model_name,local_files_only=True
)

4.2 加载学生模型

# 加载学生模型(Qwen)
student_model_name = os.path.join(current_script_dir, "../models/qwen2.5-1.5B")  # 确保模型名称正确
logger.info(f"Loading student model: {student_model_name}")
student_tokenizer = AutoTokenizer.from_pretrained(student_model_name,local_files_only=True
)
student_model = AutoModelForCausalLM.from_pretrained(student_model_name,local_files_only=True
)

4.3 数据预处理函数  

dataset.map() 是 Hugging Face datasets 库中用于对数据集进行批量预处理的核心方法。当 batched=True 时,它会将数据集分批(batch)传递给 preprocess_function,而不是逐个样本处理。这种批量处理方式效率更高,尤其适合大规模数据集。

# 数据预处理
logger.info(f"Preprocess_function")
def preprocess_function(examples):return teacher_tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)logger.info("Preprocessing train dataset")
train_dataset = train_dataset.map(preprocess_function, batched=True)
logger.info("Preprocessing eval dataset")
eval_dataset = eval_dataset.map(preprocess_function, batched=True)

 4.4 数据收集器

DataCollatorForLanguageModeling 是 Hugging Face transformers 库中的一个数据整理类(Data Collator),用于在训练语言模型(如 BERT、GPT 等)时动态生成训练样本。它可以根据任务需求(如掩码语言模型(MLM)或因果语言模型(CLM))对输入数据进行预处理。

# 数据收集器
logger.info("DataCollatorForLanguageModeling")
data_collator = DataCollatorForLanguageModeling(tokenizer=teacher_tokenizer, mlm=False)

mlm(关键参数):作用:控制是否启用**掩码语言模型(MLM)**模式。

mlm=True:随机掩码输入中的部分 token(如 BERT 训练方式),生成 [MASK] 标记。

mlm=False:禁用掩码,适用于因果语言模型(CLM)(如 GPT 训练方式),输入和标签为原始 token 序列。

4.5 定义训练参数

# 定义训练参数
logger.info("Creating trainer")
training_args = TrainingArguments(output_dir="./results",            # 训练结果保存路径eval_strategy="epoch",             # 每个 epoch 结束时评估learning_rate=5e-5,                # 学习率(默认 5e-5 是常见选择)per_device_train_batch_size=2,     # 每个设备的训练 batch size(GPU 单卡)per_device_eval_batch_size=2,      # 每个设备的评估 batch sizenum_train_epochs=3,                # 训练轮次(3 轮可能较短,需根据任务调整)weight_decay=0.01,                 # 权重衰减(L2 正则化)logging_dir="./logs",              # 日志保存路径logging_steps=100,                 # 每 100 步记录一次日志fp16=False,                        # 是否启用混合精度训练(建议开启)gradient_accumulation_steps=4,     # 梯度累积步数(等效 batch_size=8)report_to="tensorboard",           # 使用 TensorBoard 记录训练过程# tensorboard_dir="./tensorboard"  # 可选:指定 TensorBoard 日志目录
)

4.6 定义蒸馏配置

# 定义蒸馏配置  weight:添加权重,"loss": "mse"
logger.info("Creating distillation config")
distill_config = DistillationConfig(temperature=2.0,  # 温度参数,控制软标签的平滑程度hard_label_weight=0.5,  # 真实标签损失权重kd_loss_type="ce",      # 知识蒸馏损失类型(交叉熵)intermediate_matches=[  # 中间层匹配配置{"layer_T": 6,    # 教师模型的第6层"layer_S": 6,    # 学生模型的第6层"feature": "hidden",  # 匹配隐藏层特征"weight": 1.0,   # 中间层损失权重"loss": "mse"    # 使用均方误差损失}])

4.7 定义训练配置

# 定义训练配置
logger.info("Creating training config")
train_config = TrainingConfig(device="cuda" if torch.cuda.is_available() else "cpu",  # 设备选择log_dir="./logs",                                     # 日志目录output_dir="./outputs"                                # 模型输出目录# save_best_model=True,  # 是否保存最佳模型(注释状态)# save_last_model=True,  # 是否保存最后模型(注释状态)# save_model_every_epoch=True,  # 是否每轮保存模型(注释状态)# tensorboard_dir="./tensorboard"  # TensorBoard 日志目录(注释状态))

4.8 创建蒸馏器 

# 创建蒸馏器
logger.info("Creating distiller")
distiller = GeneralDistiller(train_config=train_config,        # 训练配置(包含设备、路径等)distill_config=distill_config,    # 蒸馏配置(温度、损失权重等)model_T=teacher_model,            # 教师模型model_S=student_model,            # 学生模型adaptor_T=None,                   # 教师模型适配器(未配置)adaptor_S=None                    # 学生模型适配器(未配置)
)

4.9 开始蒸馏 

# 开始蒸馏
with distiller:  # 使用蒸馏器上下文管理器,确保资源正确初始化和释放logger.info("Starting training")  # 记录训练开始日志# 初始化 Trainer,集成模型蒸馏配置trainer = Trainer(model=student_model,  # 学生模型(需要训练的小模型)args=training_args,   # 训练参数(如学习率、批次大小、设备等)train_dataset=train_dataset,  # 训练数据集(包含输入和标签)eval_dataset=eval_dataset,    # 验证数据集(用于评估模型性能)data_collator=data_collator,  # 数据批量处理函数(将单条数据组合成批次)# processing_class=teacher_tokenizer  # 注意:此处可能存在问题(见下方说明)# 正确做法:适配器或数据处理逻辑应在蒸馏配置中处理)# 开始模型训练trainer.train()  # 启动训练循环,包含前向传播、损失计算、反向传播等logger.info("Training finished")  # 记录训练结束日志

 5. 完整代码

import osimport torch
from transformers import AutoModelForCausalLM, AutoTokenizer, DataCollatorForLanguageModeling, Trainer, \TrainingArguments
from textbrewer import GeneralDistiller, TrainingConfig, DistillationConfig
from datasets import load_dataset
import logging# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)# 获取当前脚本文件的绝对路径
current_script_path = os.path.abspath(__file__)
logger.info(f"Current script path: {current_script_path}")# 获取当前脚本文件所在的目录
current_script_dir = os.path.dirname(current_script_path)
logger.info(f"Current script directory: {current_script_dir}")# 加载教师模型(DeepSeek-R1:1.5B)
teacher_model_name = os.path.join(current_script_dir, "../models/DeepSeek-R1-Distill-Qwen-1.5B")
logger.info(f"Loading teacher model: {teacher_model_name}")
teacher_tokenizer = AutoTokenizer.from_pretrained(teacher_model_name,local_files_only=True
)
teacher_model = AutoModelForCausalLM.from_pretrained(teacher_model_name,local_files_only=True
)# 加载学生模型(Qwen)
student_model_name = os.path.join(current_script_dir, "../models/qwen2.5-1.5B")  # 确保模型名称正确
logger.info(f"Loading student model: {student_model_name}")
student_tokenizer = AutoTokenizer.from_pretrained(student_model_name,local_files_only=True
)
student_model = AutoModelForCausalLM.from_pretrained(student_model_name,local_files_only=True
)# 准备数据集
datasets_name = os.path.join(current_script_dir, "../models/Dataset/wikitext-2-raw/")  # 确保模型名称正确
data_files = {"train": datasets_name+"wiki.train.raw","test": datasets_name+"wiki.test.raw"
}
logger.info(f"Loading dataset from local files: {data_files}")
dataset = load_dataset("text", data_files=data_files)
train_dataset = dataset["train"]
eval_dataset = dataset["test"]# 数据预处理
logger.info(f"Preprocess_function")
def preprocess_function(examples):return teacher_tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)logger.info("Preprocessing train dataset")
train_dataset = train_dataset.map(preprocess_function, batched=True)
logger.info("Preprocessing eval dataset")
eval_dataset = eval_dataset.map(preprocess_function, batched=True)# 数据收集器
logger.info("DataCollatorForLanguageModeling")
data_collator = DataCollatorForLanguageModeling(tokenizer=teacher_tokenizer, mlm=False)# 定义训练参数
logger.info("Creating trainer")
training_args = TrainingArguments(output_dir="./results",            # 训练结果保存路径eval_strategy="epoch",             # 每个 epoch 结束时评估learning_rate=5e-5,                # 学习率(默认 5e-5 是常见选择)per_device_train_batch_size=2,     # 每个设备的训练 batch size(GPU 单卡)per_device_eval_batch_size=2,      # 每个设备的评估 batch sizenum_train_epochs=3,                # 训练轮次(3 轮可能较短,需根据任务调整)weight_decay=0.01,                 # 权重衰减(L2 正则化)logging_dir="./logs",              # 日志保存路径logging_steps=100,                 # 每 100 步记录一次日志fp16=False,                        # 是否启用混合精度训练(建议开启)gradient_accumulation_steps=4,     # 梯度累积步数(等效 batch_size=8)report_to="tensorboard",           # 使用 TensorBoard 记录训练过程# tensorboard_dir="./tensorboard"  # 可选:指定 TensorBoard 日志目录
)# 定义蒸馏配置  weight:添加权重,"loss": "mse"
logger.info("Creating distillation config")
distill_config = DistillationConfig(temperature=2.0,  # 温度参数,控制软标签的平滑程度hard_label_weight=0.5,  # 真实标签损失权重kd_loss_type="ce",      # 知识蒸馏损失类型(交叉熵)intermediate_matches=[  # 中间层匹配配置{"layer_T": 6,    # 教师模型的第6层"layer_S": 6,    # 学生模型的第6层"feature": "hidden",  # 匹配隐藏层特征"weight": 1.0,   # 中间层损失权重"loss": "mse"    # 使用均方误差损失}]
)# 定义训练配置
logger.info("Creating training config")
train_config = TrainingConfig(device="cuda" if torch.cuda.is_available() else "cpu",  # 设备选择log_dir="./logs",                                     # 日志目录output_dir="./outputs"                                # 模型输出目录# save_best_model=True,  # 是否保存最佳模型(注释状态)# save_last_model=True,  # 是否保存最后模型(注释状态)# save_model_every_epoch=True,  # 是否每轮保存模型(注释状态)# tensorboard_dir="./tensorboard"  # TensorBoard 日志目录(注释状态)
)# 创建蒸馏器
logger.info("Creating distiller")
distiller = GeneralDistiller(train_config=train_config,        # 训练配置(包含设备、路径等)distill_config=distill_config,    # 蒸馏配置(温度、损失权重等)model_T=teacher_model,            # 教师模型model_S=student_model,            # 学生模型adaptor_T=None,                   # 教师模型适配器(未配置)adaptor_S=None                    # 学生模型适配器(未配置)
)# 开始蒸馏
with distiller:  # 使用蒸馏器上下文管理器,确保资源正确初始化和释放logger.info("Starting training")  # 记录训练开始日志# 初始化 Trainer,集成模型蒸馏配置trainer = Trainer(model=student_model,  # 学生模型(需要训练的小模型)args=training_args,  # 训练参数(如学习率、批次大小、设备等)train_dataset=train_dataset,  # 训练数据集(包含输入和标签)eval_dataset=eval_dataset,  # 验证数据集(用于评估模型性能)data_collator=data_collator,  # 数据批量处理函数(将单条数据组合成批次)# processing_class=teacher_tokenizer  # 注意:此处可能存在问题(见下方说明)# 正确做法:适配器或数据处理逻辑应在蒸馏配置中处理)# 开始模型训练trainer.train()  # 启动训练循环,包含前向传播、损失计算、反向传播等trainer.save_model()logger.info("Training finished")  # 记录训练结束日志
复制代码

参考:

模型蒸馏(Distillation)案例--从DeepSeek-R1-1.5B 到 Qwen-2.5-1.5B 的模型蒸馏 - InProsperity - 博客园

模型蒸馏(Distillation)案例--从DeepSeek-R1-1.5B 到 Qwen-2.5-1.5B 的模型蒸馏-CSDN博客

6.结合上述内容和TextBrewer,自己重新整理了一遍代码,仅供参考:

import os
import torch
import logging
from transformers import (AutoModelForCausalLM,AutoTokenizer,DataCollatorForLanguageModeling,get_linear_schedule_with_warmup
)
from textbrewer import GeneralDistiller, TrainingConfig, DistillationConfig
from datasets import load_dataset
from torch.optim import AdamW# 配置日志
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',handlers=[logging.FileHandler("distillation.log"),logging.StreamHandler()]
)
logger = logging.getLogger(__name__)# 设备设置
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
logger.info(f"Using device: {device}")# ======================
# 1. 加载模型和Tokenizer
# ======================
def load_models_and_tokenizers():"""加载教师和学生模型"""# 教师模型 (DeepSeek-R1 1.5B)teacher_model_name = "deepseek-ai/deepseek-r1-1.5b"logger.info(f"Loading teacher model: {teacher_model_name}")teacher_tokenizer = AutoTokenizer.from_pretrained(teacher_model_name)teacher_model = AutoModelForCausalLM.from_pretrained(teacher_model_name,torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32).to(device)# 学生模型 (Qwen 1.5B)student_model_name = "Qwen/Qwen1.5-1.8B"logger.info(f"Loading student model: {student_model_name}")student_tokenizer = AutoTokenizer.from_pretrained(student_model_name)student_model = AutoModelForCausalLM.from_pretrained(student_model_name,torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32).to(device)# 对齐tokenizer(关键步骤!)if teacher_tokenizer.vocab != student_tokenizer.vocab:logger.warning("Tokenizers not aligned, adding special tokens...")student_tokenizer.add_special_tokens({'pad_token': '[PAD]'})student_model.resize_token_embeddings(len(student_tokenizer))return teacher_model, student_model, teacher_tokenizer, student_tokenizer# ======================
# 2. 数据准备
# ======================
def prepare_data(student_tokenizer):"""加载并预处理数据"""# 加载数据集(示例使用wikitext)dataset = load_dataset("wikitext", "wikitext-2-raw-v1")# 预处理函数def preprocess_function(examples):return student_tokenizer(examples["text"],truncation=True,padding="max_length",max_length=512,return_tensors="pt")# 处理数据集train_dataset = dataset["train"].map(preprocess_function,batched=True,remove_columns=["text"])eval_dataset = dataset["validation"].map(preprocess_function,batched=True,remove_columns=["text"])# 数据收集器data_collator = DataCollatorForLanguageModeling(tokenizer=student_tokenizer,mlm=False)return train_dataset, eval_dataset, data_collator# ======================
# 3. 蒸馏配置
# ======================
def get_distillation_config():"""配置蒸馏参数"""return DistillationConfig(temperature=2.0,  # 初始温度temperature_scheduler=lambda x: max(0.5, 2.0 - 0.1 * x),  # 温度衰减hard_label_weight=0.3,  # 真实标签权重kd_loss_weight=0.7,  # 蒸馏损失权重kd_loss_type="ce",  # 交叉熵损失intermediate_matches=[{"layer_T": [6, 12, 18],  # 教师模型层"layer_S": [3, 6, 9],  # 学生模型层"feature": "hidden",  # 隐藏状态"loss": "cosine",  # 余弦相似度损失"weight": 0.5,"proj": ["linear", 1536, 1024]  # 维度投影},{"layer_T": [9, 15],"layer_S": [4, 7],"feature": "attention",  # 注意力矩阵"loss": "mse","weight": 0.3}])# ======================
# 4. 训练配置
# ======================
def get_training_config():"""配置训练参数"""return TrainingConfig(output_dir="./distill_output",device=device,fp16=torch.cuda.is_available(),gradient_accumulation_steps=4,ckpt_frequency=500,  # 每500步保存检查点log_steps=100,max_grad_norm=1.0,  # 梯度裁剪save_optimizer=False  # 为节省空间不保存优化器)# ======================
# 5. 优化器设置
# ======================
def get_optimizer(model):"""配置优化器和学习率调度"""optimizer = AdamW(model.parameters(),lr=5e-5,weight_decay=0.01)scheduler = get_linear_schedule_with_warmup(optimizer,num_warmup_steps=500,num_training_steps=3000)return optimizer, scheduler# ======================
# 主函数
# ======================
def main():# 1. 加载模型和数据teacher_model, student_model, teacher_tokenizer, student_tokenizer = load_models_and_tokenizers()train_dataset, eval_dataset, data_collator = prepare_data(student_tokenizer)# 2. 配置蒸馏distill_config = get_distillation_config()train_config = get_training_config()# 3. 初始化蒸馏器distiller = GeneralDistiller(train_config=train_config,distill_config=distill_config,model_T=teacher_model,model_S=student_model,adaptor_T=None,  # 使用默认适配器adaptor_S=None)# 4. 准备优化器optimizer, scheduler = get_optimizer(student_model)# 5. 开始蒸馏logger.info("Starting distillation...")with distiller:distiller.train(optimizer=optimizer,scheduler=scheduler,train_dataset=train_dataset,eval_dataset=eval_dataset,batch_size=2,num_epochs=3,data_collator=data_collator,callback=None)# 6. 保存最终模型student_model.save_pretrained("./final_student_model")student_tokenizer.save_pretrained("./final_student_model")logger.info("Distillation completed!")if __name__ == "__main__":main()

另外,可以了解Text Generation WebUI,集成不同大模型进行推理,测试。

https://github.com/oobabooga/text-generation-webui

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

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

相关文章

通过redis_exporter监控redis cluster

环境说明: 现在有一套redis cluster,部署是3主机6实例架构部署。需要采集对应的指标,满足异常监控告警,性能分析所需。 环境准备 以下环境需要提前部署完成。 redis cluser prometheus alertmanager grafna redis_exporter部署 我…

第二十天(正则表达式与功能实际运用)

在程序员一生的工作中,遇到的最多的数据就是字符串字符串里面很有可能有很多的不需要的信息我们需要从中间挑选出我们需要的如果循环去写,比较简单的时候问题不大规则多了,你的工作量会成倍上升的为了解决这个问题 ---- 正则表达式正则表达式…

0基础法考随手笔记 03(刑诉05 刑事证据与证明+06 强制措施)

1.如何区分书证和电子数据 书面材料是否为书证?→ 看内容是否直接源于案件事实(不是 “记录别人陈述” 的载体)。 证据清单是否为证据?→ 看谁做的清单(侦查人员做的勘查笔录是证据,当事人做的目录不是&…

资产负债表及其数据获取

文章目录资产负债表及其数据获取资产负债表资产负债表在股票投资中的意义AKShare中的资产负债表数据接口(深沪为例)接口描述调用示例总结资产负债表及其数据获取 资产负债表 资产负债表(Balance Sheet)是反映企业在某一特定日期财…

数据仓库深度探索系列 | 开篇:开启数仓建设新征程

数据仓库深度探索系列 | 开篇:开启数仓建设新征程 在当今信息技术飞速发展的背景下,企业面临着数据量的爆炸式增长。企业不仅要高效管理海量数据,还需从中提取关键信息以支持复杂决策。数据仓库已从单纯的数据存储工具,演变为支持…

Linux如何执行系统调用及高效执行系统调用:深入浅出的解析

文章目录如何执行系统调用及高效执行系统调用:深入浅出的解析一、什么是系统调用?1.1 系统调用的作用1.2 系统调用的分类二、如何执行系统调用?2.1 系统调用的触发2.2 库函数与系统调用的关系2.3 系统调用的示例2.4 错误处理三、如何高效执行…

基于 XGBoost 与 SHAP 的医疗自动化办公与可视化系统(上)

摘要 随着信息技术的飞速发展和医疗健康数据的爆炸式增长,现代医疗机构面临着日益复杂的数据处理挑战。医生和行政人员常常需要花费大量时间在数据提取、整理、分析和报告生成等重复性、事务性的工作上,这不仅降低了工作效率,也限制了医护人员将更多精力投入到直接的患者护…

基于Kafka实现简单的延时队列

生命无罪,健康万岁,我是laity。 我曾七次鄙视自己的灵魂: 第一次,当它本可进取时,却故作谦卑; 第二次,当它在空虚时,用爱欲来填充; 第三次,在困难和容易之间&…

OceanBase 4.3.5 解析:DDL性能诊断

背景DDL操作通常耗时较长,特别是涉及补数据流程的DDL语句。在执行过程中,用户面临两个主要痛点:一是无法实时获取DDL执行进度,难以区分长时间运行是正常现象还是由内部异常导致的停滞;二是执行效率经常低于预期&#x…

幸福网咖订座点餐小程序的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBoot微信小程序持久层框架MyBaits成功系统案例:参考代码数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续…

C语言————练习题册(答案版)

目录 每日更新5-10题,感兴趣可以订阅 一.理解函数、操作符、占位符 1.1 欢迎来到C语言的世界 1.2 输入和输出 1.3 浮点数的打印 1.4 字符串的打印 1.14 I am iron man 1.5 求和运算 1.6 计算比例 1.7 求商求余 1.8 不同数位上的数字 1.8.1 求个位数 1.8…

haproxy配置详解

1、haproxy简介 HAProxy是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件 是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计 企业版网站&#xff…

计网-TCP可靠传输

TCP(传输控制协议)的可靠传输是通过一系列机制保证数据准确、有序、不丢失地到达接收方。以下是TCP可靠传输的详细过程及核心机制:1. 数据分块与序列号(Seq)分块:应用层数据被分割成适合传输的TCP报文段&am…

数智管理学(三十九)

第三章 数智化对管理理论的冲击第三节 系统理论与生态化管理的强化系统理论作为理解企业运作与环境互动的重要框架,一直强调企业是一个由多个相互关联子系统构成的整体,其核心要素包括整体性、开放性、动态性和反馈机制。在传统管理视角下,这…

哈希表(c语言)

文章目录哈希表哈希表知识点哈希表概念负载因子哈希表的优缺点哈希冲突哈希函数常见哈希函数处理哈希冲突开放定址法线性探测二次探测链地址法哈希表的实现哈希表的核心:HashMap核心函数:从创建到销毁创建哈希表:hashmap_create()销毁哈希表:hashmap_des…

【Canvas与旗帜】条纹版大明三辰旗

【成图】【代码】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>十三条纹版大明三辰旗 Draft1</title><style type"text/…

【Java】空指针(NullPointerException)异常深度攻坚:从底层原理到架构级防御,老司机的实战经验

写Java代码这些年&#xff0c;空指针异常&#xff08;NullPointerException&#xff09;就像甩不掉的影子。线上排查问题时&#xff0c;十次有八次最后定位到的都是某个对象没处理好null值。但多数人解决问题只停留在加个if (obj ! null)的层面&#xff0c;没从根本上想过为什么…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-评论用户时间占比环形饼状图实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解主页-评论用户时间占比环形饼状图实现 视频…

Redis面试精讲 Day 5:Redis内存管理与过期策略

【Redis面试精讲 Day 5】Redis内存管理与过期策略 开篇 欢迎来到"Redis面试精讲"系列的第5天&#xff01;今天我们将深入探讨Redis内存管理与过期策略&#xff0c;这是面试中经常被问及的核心知识点。对于后端工程师而言&#xff0c;理解Redis如何高效管理内存、处…

ICMPv6报文类型详解表

一、错误报文类型&#xff08;Type 1-127&#xff09;Type值名称Code范围触发条件示例典型用途1Destination Unreachable0-60: 无路由到目标1: 通信被管理员禁止2: 地址不可达3: 端口不可达4: 分片需要但DF标志设置5: 源路由失败6: 目的地址不可达网络故障诊断2Packet Too Big0…