人工智能大模型应用开发:从微调适配到场景落地

人工智能大模型应用开发:从微调适配到场景落地

一、人工智能大模型应用开发:从微调适配到场景落地

在这里插入图片描述

1.1 本章学习目标与重点

💡 掌握大模型应用开发的核心流程,包括模型选型、微调适配、功能封装、部署上线等关键环节;
💡 熟练运用主流大模型框架(Hugging Face Transformers、LangChain、LlamaIndex 等),实现文本生成、问答系统、智能助手等常见应用;
💡 理解大模型微调的核心技术(全参数微调、LoRA、QLoRA 等),能够根据数据规模和硬件资源选择合适的适配方案;
💡 通过真实场景案例(企业知识库问答、智能客服、代码生成助手),掌握大模型从技术适配到业务落地的端到端开发能力。

⚠️ 重点关注:大模型的上下文窗口限制、生成内容的准确性与安全性、微调过程中的显存优化、以及生产环境下的性能与稳定性平衡。

1.2 大模型应用开发基础:选型与环境搭建

大模型应用开发的第一步是明确业务需求,选择合适的模型并搭建稳定的开发环境。本节将从模型选型原则、主流开发框架介绍、环境搭建实操三个维度,为后续开发奠定基础。

1.2.1 大模型选型核心原则

大模型选型需兼顾业务需求、性能指标、资源约束三大核心因素,避免盲目追求大参数量模型导致的开发成本浪费。

1. 业务需求匹配
  • 文本生成类(如文案创作、小说续写):优先选择擅长创造性写作的模型(如 GPT-4、Claude 3、Llama 3);
  • 知识问答类(如企业知识库、行业咨询):优先选择知识覆盖全面、推理能力强的模型(如 GPT-4o、Gemini Pro、通义千问);
  • 代码生成类(如代码补全、bug 修复):优先选择代码领域优化的模型(如 CodeLlama、StarCoder、GPT-4 Code);
  • 多模态类(如图文生成、语音交互):选择支持多模态输入输出的模型(如 GPT-4o、Gemini Ultra、文心一言 4.0);
  • 私有化部署类(如涉密场景、内网应用):选择支持本地部署的开源模型(如 Llama 2/3、Mistral、Qwen)。
2. 性能指标评估
  • 生成质量:通过困惑度(Perplexity)、BLEU 分数、人工评估(流畅度、准确性、相关性)衡量;
  • 推理速度:关注单轮请求延迟(Latency)和吞吐量(Throughput),尤其高并发场景需优先选择轻量化模型;
  • 上下文窗口:根据业务场景的输入长度需求选择(如短文本交互选 4k/8k 窗口,长文档处理选 32k/128k 窗口);
  • 成本预算:API 调用类模型需评估 Token 消耗成本,私有化部署类需考虑硬件采购和运维成本。
3. 资源约束适配
硬件资源推荐模型类型典型应用场景
消费级 GPU(16GB 显存)7B/13B 开源模型(如 Llama 3 8B、Mistral 7B)个人开发、小型应用、原型验证
企业级 GPU(32GB/48GB 显存)34B/70B 开源模型(如 Llama 3 70B、Qwen 72B)部门级应用、中等规模私有化部署
数据中心 GPU(80GB+ 显存)100B+ 开源模型(如 Llama 3 400B、GPT-4 本地部署版)企业级核心业务、大规模私有化部署
无 GPU/低资源环境API 调用类模型(如 OpenAI API、阿里云百炼 API)快速迭代、轻量级应用、成本敏感场景

💡 实战技巧:原型开发阶段优先使用 API 调用类模型(如 GPT-3.5 Turbo)快速验证需求,产品化阶段再根据成本和隐私要求,选择开源模型私有化部署或继续使用 API 服务。

1.2.2 主流大模型开发框架

大模型应用开发离不开高效的框架支持,以下是工业界最常用的三大类框架,覆盖模型加载、微调、功能封装、部署全流程。

1. 模型加载与微调框架:Hugging Face Transformers

Transformers 是大模型开发的核心框架,支持 1000+ 预训练模型,提供统一的 API 接口,简化模型加载、推理、微调流程,兼容 PyTorch、TensorFlow 等主流深度学习框架。

核心功能:

  • 一键加载预训练模型(如 Llama、GPT、BERT 等);
  • 支持文本生成、文本分类、问答、翻译等多种任务;
  • 内置多种微调策略(全参数微调、LoRA、QLoRA 等);
  • 集成 Tokenizer、数据预处理工具,降低开发门槛。
2. 应用编排框架:LangChain

LangChain 专注于大模型应用的"流程编排",通过链(Chain)、代理(Agent)、记忆(Memory)等组件,将大模型与外部工具(数据库、API、知识库)集成,快速构建复杂应用(如问答系统、智能助手)。

核心功能:

  • 文本分割、嵌入(Embedding)、向量存储集成,支持知识库构建;
  • 链结构设计,串联多个任务步骤(如"检索+生成"、“工具调用+结果整理”);
  • 代理机制,支持大模型自动选择工具解决复杂问题;
  • 记忆组件,支持对话上下文管理,提升交互连贯性。
3. 知识库构建框架:LlamaIndex

LlamaIndex(原 GPT Index)专为"大模型+私有知识库"场景设计,优化了长文档处理、知识检索、上下文整合能力,让大模型能够高效利用私有数据进行推理。

核心功能:

  • 支持多种数据格式(文档、PDF、数据库、API 数据)的加载与解析;
  • 提供多种索引结构(列表索引、向量索引、树状索引),适配不同知识库场景;
  • 优化上下文窗口利用,支持超长文档的分段处理与整合;
  • 与 LangChain、Transformers 无缝集成,降低技术栈切换成本。

1.2.3 开发环境搭建实操

以下以"开源模型微调+LangChain 应用开发"为目标,搭建完整的开发环境(基于 Ubuntu 20.04 + NVIDIA GPU)。

1. 基础依赖安装
# 更新系统依赖sudoapt-get update &&sudoapt-getinstall -y \ python3-pip \ python3-dev \ build-essential \git\ libgl1-mesa-glx \ libglib2.0-0 # 升级 pip pip3 install --upgrade pip 
2. 深度学习框架安装(PyTorch)
# 安装 PyTorch 2.1.0(适配 CUDA 11.8) pip3 installtorch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118 # 验证 PyTorch 安装(是否支持 GPU) python3 -c "import torch; print('CUDA 支持:', torch.cuda.is_available())"# 输出 True 表示成功
3. 核心开发框架安装
# 安装 Hugging Face 生态 pip3 installtransformers==4.38.2 datasets==2.18.0 peft==0.8.2 accelerate==0.30.1 bitsandbytes==0.43.0 # 安装 LangChain 生态 pip3 installlangchain==0.2.5 langchain-community==0.2.5 langchain-openai==0.1.7 # 安装 LlamaIndex pip3 install llama-index==0.10.31 # 安装向量数据库(用于知识库存储) pip3 installchromadb==0.4.24 faiss-cpu==1.7.4 # faiss-gpu 需单独安装:pip3 install faiss-gpu# 安装其他工具(文档解析、日志、可视化) pip3 installpypdf==4.1.0 python-dotenv==1.0.1 tqdm==4.66.2 matplotlib==3.8.4 
4. 环境验证
# 验证 Transformers 模型加载from transformers import AutoModelForCausalLM, AutoTokenizer # 加载小型开源模型(Llama 3 8B Instruct,需提前申请访问权限) model_name ="meta-llama/Meta-Llama-3-8B-Instruct" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, device_map="auto",# 自动分配设备(CPU/GPU) load_in_8bit=True# 8bit 量化加载,节省显存)# 测试文本生成 inputs = tokenizer("请介绍人工智能大模型的应用场景", return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)print(tokenizer.decode(outputs[0], skip_special_tokens=True))# 验证 LangChain 链功能from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.llms import HuggingFacePipeline # 封装 Transformers 模型为 LangChain LLM pipeline = transformers.pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=200, temperature=0.7) llm = HuggingFacePipeline(pipeline=pipeline)# 构建简单生成链 prompt = PromptTemplate( input_variables=["topic"], template="请围绕 {topic} 写一段 100 字左右的介绍") chain = LLMChain(llm=llm, prompt=prompt)print(chain.run("大模型微调技术"))

✅ 若能成功输出文本生成结果,说明开发环境搭建完成。

1.3 大模型微调核心技术:适配私有数据与业务场景

预训练大模型的通用知识难以完全满足特定业务需求(如企业内部知识库问答、行业专属任务),因此需要通过微调让模型学习私有数据中的知识,提升应用效果。本节将详解主流微调技术的原理、实操与适用场景。

1.3.1 大模型微调技术对比与选型

大模型微调技术的核心目标是"在有限资源下,让模型快速学习私有数据的知识",不同技术在显存占用、训练速度、效果提升上差异显著。

微调技术核心原理显存占用训练速度效果提升适用场景
全参数微调调整模型所有参数,让模型完全适配数据高(70B 模型需 80GB+ 显存)数据量充足(10万+ 样本)、资源充足场景
LoRA(Low-Rank Adaptation)冻结模型主干参数,仅训练低秩矩阵适配器中(70B 模型需 24GB+ 显存)数据量中等(1万-10万样本)、平衡效果与成本
QLoRA(Quantized LoRA)量化模型(4bit/8bit)+ LoRA 微调低(70B 模型需 16GB+ 显存)良-优数据量少(1千-1万样本)、消费级 GPU 开发
提示微调(Prompt Tuning)冻结模型参数,仅训练提示相关嵌入层极低极快一般数据量极少(<1千样本)、快速适配简单任务

💡 选型建议:大多数业务场景(如企业知识库问答、智能客服)优先选择 QLoRA 或 LoRA 微调,以"低成本、高效果"为核心目标;仅当数据量充足且有充足硬件资源时,才考虑全参数微调。

1.3.2 QLoRA 微调实操:消费级 GPU 适配开源大模型

QLoRA 是目前最流行的微调技术,通过 4bit 量化模型降低显存占用,同时结合 LoRA 训练低秩矩阵,在消费级 GPU(如 RTX 3090/4090,16GB/24GB 显存)上即可完成 70B 级模型微调。以下以"企业知识库问答"为例,详解 QLoRA 微调全流程。

1. 数据准备:构建高质量微调数据集

微调数据的质量直接决定模型效果,需遵循"格式统一、内容相关、标注准确"原则。常见的微调数据格式为 JSONL,每条样本包含"输入(prompt)“和"输出(response)”。

(1)数据集格式示例(企业知识库问答)
{"prompt":"请问公司的员工年假政策是什么?","response":"公司员工年假政策如下:1. 入职满1年不满3年,年假5天;2. 入职满3年不满10年,年假10天;3. 入职满10年,年假15天;4. 年假可分次使用,当年未休完的部分不累计至次年。"}{"prompt":"报销流程需要提交哪些材料?","response":"报销需提交以下材料:1. 正规发票(抬头为公司全称);2. 费用明细单(注明用途、金额、日期);3. 相关支撑材料(如出差申请单、会议通知等);4. 报销申请表(需部门负责人签字)。"}
(2)数据集加载与预处理(使用 Hugging Face Datasets)
import json import datasets from datasets import Dataset # 加载本地 JSONL 数据集defload_custom_dataset(data_path):withopen(data_path,"r", encoding="utf-8")as f: data =[json.loads(line)for line in f]# 转换为 Hugging Face Dataset 格式 dataset = Dataset.from_list(data)# 划分训练集和验证集(9:1) dataset = dataset.train_test_split(test_size=0.1, seed=42)return dataset["train"], dataset["test"]# 加载数据 train_dataset, val_dataset = load_custom_dataset("company_kb_qa.jsonl")print(f"训练集样本数:{len(train_dataset)},验证集样本数:{len(val_dataset)}")# 数据预处理:格式化 prompt(适配 Llama 3 指令格式)defformat_prompt(sample): prompt =f"""<<|begin_of_solution|> 用户问题:{sample['prompt']} 回答:{sample['response']}<<|end_of_solution|>"""return{"text": prompt}# 应用格式化函数 train_dataset = train_dataset.map(format_prompt) val_dataset = val_dataset.map(format_prompt)# 查看处理后的数据print("处理后的数据示例:", train_dataset[0]["text"])
2. 模型与 Tokenizer 加载
from transformers import( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline )from peft import LoraConfig, prepare_model_for_kbit_training, get_peft_model # 模型名称(Llama 3 8B Instruct) model_name ="meta-llama/Meta-Llama-3-8B-Instruct"# 配置 4bit 量化参数 bnb_config = BitsAndBytesConfig( load_in_4bit=True,# 启用 4bit 加载 bnb_4bit_use_double_quant=True,# 双量化,进一步降低显存占用 bnb_4bit_quant_type="nf4",# 量化类型(nf4 对大模型更友好) bnb_4bit_compute_dtype=torch.bfloat16 # 计算精度)# 加载 Tokenizer tokenizer = AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token = tokenizer.eos_token # 设置 pad token(Llama 3 默认无 pad token) tokenizer.padding_side ="right"# 右填充,避免影响生成效果# 加载量化模型 model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto",# 自动分配设备 trust_remote_code=True)# 准备模型用于 kbit 训练 model = prepare_model_for_kbit_training(model)# 配置 LoRA 参数 lora_config = LoraConfig( r=8,# 低秩矩阵维度(越大效果越好,但显存占用越高) lora_alpha=32,# 缩放因子(一般为 r 的 2-4 倍) target_modules=["q_proj","v_proj"],# 目标模块(Llama 3 注意力层的查询和值投影层) lora_dropout=0.05,# Dropout 比例 bias="none",# 不训练偏置项 task_type="CAUSAL_LM"# 任务类型(因果语言模型))# 应用 LoRA 配置到模型 model = get_peft_model(model, lora_config) model.print_trainable_parameters()# 打印可训练参数比例(一般为 0.1%-1%)

运行结果示例:

trainable params: 1,677,824 || all params: 8,031,870,976 || trainable%: 0.0209 

可训练参数仅占总参数的 0.02%,显存占用可控制在 10GB 以内。

3. 配置训练参数(使用 SFTTrainer)
from trl import SFTTrainer from transformers import TrainingArguments # 训练参数配置 training_args = TrainingArguments( output_dir="./llama3-8b-company-qa-lora",# 模型保存路径 per_device_train_batch_size=4,# 单设备训练批量大小(根据显存调整) per_device_eval_batch_size=4,# 单设备验证批量大小 gradient_accumulation_steps=4,# 梯度累积步数(模拟更大批量) learning_rate=2e-4,# 学习率(LoRA 微调一般为 1e-4~3e-4) num_train_epochs=3,# 训练轮数(数据量少则增加轮数) logging_steps=10,# 日志打印步数 evaluation_strategy="epoch",# 每轮 epoch 验证一次 save_strategy="epoch",# 每轮 epoch 保存一次模型 fp16=True,# 启用 FP16 训练,提升速度 push_to_hub=False,# 不推送到 Hugging Face Hub report_to="none",# 不使用 wandb 等日志工具 optim="paged_adamw_8bit",# 优化器(适配 8bit 量化) lr_scheduler_type="cosine",# 学习率调度器(余弦退火) warmup_ratio=0.05# 热身比例(前 5% 步数逐步提升学习率))# 初始化 SFTTrainer trainer = SFTTrainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=val_dataset, tokenizer=tokenizer, peft_config=lora_config, max_seq_length=512,# 最大序列长度 packing=False# 不启用数据打包(简单任务关闭即可))# 开始训练 trainer.train()# 保存 LoRA 适配器(仅保存训练的 LoRA 参数,体积小) trainer.save_model("./llama3-8b-company-qa-lora-final")print("QLoRA 微调完成,LoRA 适配器已保存")
4. 微调后模型推理与效果验证
# 加载微调后的模型(基座模型 + LoRA 适配器)from peft import PeftModel, PeftConfig # 加载 LoRA 配置 peft_config = PeftConfig.from_pretrained("./llama3-8b-company-qa-lora-final")# 加载基座模型 base_model = AutoModelForCausalLM.from_pretrained( peft_config.base_model_name_or_path, quantization_config=bnb_config, device_map="auto", trust_remote_code=True)# 加载 LoRA 适配器 fine_tuned_model = PeftModel.from_pretrained(base_model,"./llama3-8b-company-qa-lora-final")# 构建推理函数defgenerate_answer(question):# 格式化输入(与微调数据格式一致) prompt =f"""<<|begin_of_solution|> 用户问题:{question} 回答:<<|end_of_solution|>"""# Tokenize 输入 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)# 生成回答 outputs = fine_tuned_model.generate(**inputs, max_new_tokens=150, temperature=0.3,# 降低随机性,提升准确性 top_p=0.9, do_sample=True, pad_token_id=tokenizer.eos_token_id )# 解码输出 answer = tokenizer.decode(outputs[0], skip_special_tokens=True)# 提取回答部分(去除 prompt) answer = answer.split("回答:")[-1].strip()return answer # 测试推理效果 test_questions =["请问入职满5年的员工有多少天年假?","报销需要提交哪些材料?","年假可以分次使用吗?"]for q in test_questions:print(f"问题:{q}")print(f"回答:{generate_answer(q)}\n")

运行结果示例:

问题:请问入职满5年的员工有多少天年假? 回答:入职满3年不满10年的员工,年假为10天。因此入职满5年的员工可享受10天年假。 问题:报销需要提交哪些材料? 回答:报销需提交以下材料:1. 正规发票(抬头为公司全称);2. 费用明细单(注明用途、金额、日期);3. 相关支撑材料(如出差申请单、会议通知等);4. 报销申请表(需部门负责人签字)。 问题:年假可以分次使用吗? 回答:可以。公司年假政策规定,年假可分次使用,当年未休完的部分不累计至次年。 

✅ 微调后的模型能够准确回答企业知识库相关问题,效果显著优于未微调的基座模型。

1.3.3 LoRA 模型合并与部署准备

微调完成后,LoRA 适配器仅包含训练的低秩矩阵参数(体积通常为几 MB 到几十 MB),需与基座模型合并才能独立部署。

1. 模型合并(4bit 量化模型 → FP16 完整模型)
from peft import PeftModel, PeftConfig from transformers import AutoModelForCausalLM, AutoTokenizer # 加载 LoRA 配置和基座模型 peft_config = PeftConfig.from_pretrained("./llama3-8b-company-qa-lora-final") base_model = AutoModelForCausalLM.from_pretrained( peft_config.base_model_name_or_path, device_map="auto", torch_dtype=torch.float16,# 以 FP16 精度加载 trust_remote_code=True)# 加载并合并 LoRA 适配器 merged_model = PeftModel.from_pretrained(base_model,"./llama3-8b-company-qa-lora-final") merged_model = merged_model.merge_and_unload()# 合并并卸载 LoRA 适配器# 加载 Tokenizer tokenizer = AutoTokenizer.from_pretrained(peft_config.base_model_name_or_path) tokenizer.pad_token = tokenizer.eos_token # 保存合并后的模型 merged_model.save_pretrained("./llama3-8b-company-qa-merged") tokenizer.save_pretrained("./llama3-8b-company-qa-merged")print("模型合并完成,已保存完整模型")

合并后的模型体积约为 16GB(FP16 精度),可直接用于部署。

2. 模型量化(可选,进一步降低部署显存占用)
# 将合并后的 FP16 模型量化为 INT8,用于低显存部署from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig quantization_config = BitsAndBytesConfig( load_in_8bit=True, bnb_8bit_use_double_quant=True, bnb_8bit_quant_type="nf4", bnb_8bit_compute_dtype=torch.float16 )# 加载并量化模型 quantized_model = AutoModelForCausalLM.from_pretrained("./llama3-8b-company-qa-merged", quantization_config=quantization_config, device_map="auto", trust_remote_code=True)# 保存量化模型 quantized_model.save_pretrained("./llama3-8b-company-qa-quantized")print("INT8 量化模型保存完成,体积约 8GB")

1.4 大模型应用开发实战:三大典型场景落地

基于前文的基础框架和微调技术,本节将聚焦三大典型场景(企业知识库问答、智能客服、代码生成助手),详细讲解从功能设计到部署上线的完整开发流程。

1.4.1 场景一:企业知识库问答系统(LangChain + 向量数据库)

企业知识库问答系统的核心需求是让大模型能够基于企业私有文档(如 PDF、Word、知识库文章)回答用户问题,无需手动微调即可快速适配。核心技术路径为"文档解析→文本分割→嵌入生成→向量存储→检索增强生成(RAG)"。

1. 系统架构设计

企业文档(PDF/Word/TXT)

文档解析与文本分割

Embedding 生成(文本→向量)

向量数据库存储(Chroma/FAISS)

用户问题

问题 Embedding 生成

向量数据库检索相关文本

大模型整合上下文+生成回答

返回回答给用户

2. 完整开发代码
(1)文档解析与文本分割
from langchain.document_loaders import PyPDFLoader, DirectoryLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 加载企业文档(PDF 文件夹)defload_company_documents(doc_dir):# 配置 PDF 加载器 loader = DirectoryLoader( doc_dir, glob="*.pdf", loader_cls=PyPDFLoader, show_progress=True)# 加载文档 documents = loader.load()print(f"加载文档数:{len(documents)}")# 文本分割(解决大模型上下文窗口限制) text_splitter = RecursiveCharacterTextSplitter( chunk_size=500,# 每个文本块大小(字符数) chunk_overlap=50,# 文本块重叠部分(保证上下文连贯性) length_function=len, separators=["\n\n","\n",". "," ",""])# 执行分割 splits = text_splitter.split_documents(documents)print(f"分割后文本块数:{len(splits)}")return splits # 加载文档(示例:企业员工手册文件夹) document_splits = load_company_documents("./company_documents")
(2)构建向量数据库
from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma # 配置 Embedding 模型(使用开源中文 Embedding 模型) embedding_model = HuggingFaceEmbeddings( model_name="thenlper/gte-base-zh",# 中文 Embedding 模型,效果优于默认模型 model_kwargs={"device":"cuda"},# 启用 GPU 加速 encode_kwargs={"normalize_embeddings":True}# 归一化向量,提升检索效果)# 构建向量数据库(Chroma,轻量级开源向量库) vector_db = Chroma.from_documents( documents=document_splits, embedding=embedding_model, persist_directory="./chroma_company_kb",# 向量库保存路径 collection_name="company_manual") vector_db.persist()print("向量数据库构建完成")# 测试检索功能 query ="员工年假政策是什么?" retrieved_docs = vector_db.similarity_search(query, k=3)# 检索 Top3 相关文本块print("检索到的相关文本:")for i, doc inenumerate(retrieved_docs):print(f"\n{i+1}. {doc.page_content[:200]}...")
(3)构建 RAG 链(检索+生成)
from langchain.chains import RetrievalQA from langchain.llms import HuggingFacePipeline from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline # 加载微调后的企业问答模型(或基座模型) model_name ="./llama3-8b-company-qa-quantized" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, device_map="auto", trust_remote_code=True)# 封装为 LangChain LLM llm_pipeline = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=300, temperature=0.3, top_p=0.9, pad_token_id=tokenizer.eos_token_id ) llm = HuggingFacePipeline(pipeline=llm_pipeline)# 构建检索增强生成链 rag_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff",# 将所有检索到的文本块拼接为上下文 retriever=vector_db.as_retriever( search_kwargs={"k":3}# 每次检索 3 个相关文本块), return_source_documents=True,# 返回检索到的源文档(用于溯源) chain_type_kwargs={"prompt":""" 你是企业知识库问答助手,必须基于以下提供的上下文信息回答用户问题。 如果上下文没有相关信息,直接回复"抱歉,没有找到相关答案",不要编造信息。 上下文:{context} 用户问题:{question} 回答: """})# 测试 RAG 链defask_qa_system(question): result = rag_chain({"query": question}) answer = result["result"] sources =[doc.page_content[:100]+"..."for doc in result["source_documents"]]return answer, sources # 测试问题 test_question ="入职满8年的员工有多少天年假?" answer, sources = ask_qa_system(test_question)print(f"问题:{test_question}")print(f"回答:{answer}")print(f"参考来源:{sources}")

运行结果示例:

问题:入职满8年的员工有多少天年假? 回答:入职满3年不满10年的员工,年假为10天。因此入职满8年的员工可享受10天年假。 参考来源:['公司员工年假政策如下:1. 入职满1年不满3年,年假5天;2. 入职满3年不满10年,年假10天;3. 入职满10年,年假15天;4. 年假可分次使用...', ...] 
3. 系统部署(FastAPI + Uvicorn)
from fastapi import FastAPI, Query from fastapi.responses import JSONResponse import uvicorn # 初始化 FastAPI 应用 app = FastAPI(title="企业知识库问答系统", version="1.0")# 加载 RAG 链(已在前面代码中初始化,此处省略重复代码)# ...# 定义 API 接口@app.get("/qa", summary="企业知识库问答")asyncdefcompany_qa( question:str= Query(..., description="用户问题"), k:int= Query(3, description="检索相关文本块数量")):try:# 调整检索数量 rag_chain.retriever.search_kwargs["k"]= k # 执行问答 result = rag_chain({"query": question}) answer = result["result"] sources =[{"content": doc.page_content,"metadata": doc.metadata }for doc in result["source_documents"]]# 构建响应 response ={"status":"success","question": question,"answer": answer,"sources": sources }return JSONResponse(content=response)except Exception as e:return JSONResponse( content={"status":"error","message":str(e)}, status_code=500)# 健康检查接口@app.get("/health", summary="服务健康检查")asyncdefhealth_check():return JSONResponse(content={"status":"healthy","service":"company-qa-system"})if __name__ =="__main__": uvicorn.run(app, host="0.0.0.0", port=8000, workers=1)

启动服务后,可通过 curl 或 Postman 调用 API:

curl"http://localhost:8000/qa?question=报销需要提交哪些材料?"

1.4.2 场景二:智能客服系统(对话记忆 + 意图识别)

智能客服系统的核心需求是"多轮对话连贯、意图识别准确、能够解决用户常见问题",需结合对话记忆(Memory)和意图识别功能,提升交互体验。

1. 系统核心组件
  • 意图识别:识别用户问题意图(如"查询订单"、“投诉反馈”、“账户咨询”),路由到对应处理逻辑;
  • 对话记忆:记录多轮对话历史,让客服能够理解上下文(如用户先问"如何查订单",再问"它的物流状态",系统需知道"它"指订单);
  • 知识库检索:针对常见问题,通过 RAG 从知识库中获取答案;
  • 人工转接:复杂问题无法解决时,转接人工客服。
2. 完整开发代码
(1)意图识别模块(基于文本分类模型)
from transformers import AutoModelForSequenceClassification, AutoTokenizer, pipeline # 加载中文意图识别模型(开源模型:bert-base-chinese-finetuned-intent) intent_model_name ="uer/bert-base-chinese-finetuned-dianping-chinese-intent" intent_tokenizer = AutoTokenizer.from_pretrained(intent_model_name) intent_classifier = pipeline("text-classification", model=AutoModelForSequenceClassification.from_pretrained(intent_model_name), tokenizer=intent_tokenizer, device_map="auto")# 扩展意图类型(适配客服场景) INTENT_MAPPING ={"查询订单":["查订单","订单状态","订单查询","我的订单"],"物流咨询":["物流","快递","配送","发货"],"退款售后":["退款","退货","售后","换货"],"账户问题":["登录","注册","密码","账户"],"产品咨询":["产品功能","使用方法","规格","价格"],"投诉反馈":["投诉","反馈","建议","问题"],"其他":[]}# 意图识别函数defrecognize_intent(question):# 先通过关键词匹配快速识别for intent, keywords in INTENT_MAPPING.items():ifany(keyword in question for keyword in keywords):return intent # 关键词匹配失败,使用模型预测 result = intent_classifier(question)[0]# 模型输出映射到自定义意图(此处简化处理,实际需根据模型输出调整)return"其他"if result["score"]<0.7else"产品咨询"# 测试意图识别 test_questions =["我的订单什么时候发货?","如何申请退款?","忘记登录密码了怎么办?","这个产品支持无线充电吗?"]for q in test_questions:print(f"问题:{q},意图:{recognize_intent(q)}")
(2)对话记忆与多轮对话链
from langchain.chains import ConversationChain from langchain.memory import ConversationBufferWindowMemory from langchain.prompts import PromptTemplate # 配置对话记忆(保留最近 3 轮对话) conversation_memory = ConversationBufferWindowMemory( k=3,# 保留最近 3 轮 return_messages=True,# 返回 Message 对象,便于格式化 memory_key="history"# 记忆在 prompt 中的变量名)# 配置对话 prompt conversation_prompt = PromptTemplate( input_variables=["history","input"], template=""" 你是智能客服助手,负责解答用户关于产品、订单、物流、售后等问题。 对话历史:{history} 用户当前问题:{input} 回答要求: 1. 基于对话历史理解上下文,保持回答连贯; 2. 先识别用户意图,再针对性解答; 3. 常见问题优先使用知识库信息,无相关信息时如实告知; 4. 语言简洁友好,避免使用专业术语。 回答: """)# 构建对话链 conversation_chain = ConversationChain( llm=llm,# 复用前面的大模型 memory=conversation_memory, prompt=conversation_prompt, verbose=True# 打印详细日志(调试用))# 测试多轮对话defchat_with_customer(user_input):# 识别意图 intent = recognize_intent(user_input)print(f"意图识别结果:{intent}")# 执行对话链 response = conversation_chain.run(input=user_input)return response # 多轮对话测试 chat_history =["你好,我想查一下我的订单","订单号是 OD123456","这个订单的物流状态怎么样了?"]for input_text in chat_history:print(f"\n用户:{input_text}")print(f"客服:{chat_with_customer(input_text)}")

运行结果示例:

用户:你好,我想查一下我的订单 意图识别结果:查询订单 客服:你好!为了帮你查询订单,请提供你的订单号,我会为你核实订单状态~ 用户:订单号是 OD123456 意图识别结果:查询订单 客服:已收到你的订单号 OD123456~ 请你稍候,我正在查询物流状态... 用户:这个订单的物流状态怎么样了? 意图识别结果:物流咨询 客服:根据查询,你的订单 OD123456 已于今天上午 10:30 发货,目前处于"运输中"状态,预计明天送达,请你耐心等待~ 
(3)人工转接逻辑集成
defchat_with_customer_v2(user_input): intent = recognize_intent(user_input)# 复杂意图(如投诉反馈)直接转接人工if intent =="投诉反馈":return"非常抱歉给你带来不好的体验!已为你转接人工客服,请你描述具体问题,工作人员会尽快为你处理~"# 其他意图通过对话链解答 response = conversation_chain.run(input=user_input)# 检测用户是否明确要求转接人工ifany(word in user_input for word in["人工","转接","客服人员"]):return"已为你转接人工客服,请你稍候..."return response # 测试人工转接print("\n用户:我要投诉,产品质量有问题!")print(f"客服:{chat_with_customer_v2('我要投诉,产品质量有问题!')}")

1.4.3 场景三:代码生成助手(代码理解 + 多语言支持)

代码生成助手的核心需求是"根据自然语言描述生成代码、修复代码 bug、解释代码功能",需适配多种编程语言(Python、Java、JavaScript 等),并保证代码的正确性和可运行性。

1. 核心功能设计
  • 代码生成:根据自然语言需求生成指定语言的代码;
  • 代码修复:输入有 bug 的代码和错误信息,生成修复后的代码;
  • 代码解释:解释现有代码的功能、逻辑和优化建议;
  • 代码转换:将一种语言的代码转换为另一种语言。
2. 完整开发代码
(1)代码生成模块
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline # 加载代码生成模型(CodeLlama 7B Instruct,专为代码任务优化) code_model_name ="codellama/CodeLlama-7b-Instruct-hf" code_tokenizer = AutoTokenizer.from_pretrained(code_model_name) code_model = AutoModelForCausalLM.from_pretrained( code_model_name, device_map="auto", load_in_8bit=True, trust_remote_code=True)# 配置代码生成 pipeline code_generator = pipeline("text-generation", model=code_model, tokenizer=code_tokenizer, max_new_tokens=500, temperature=0.4, top_p=0.95, pad_token_id=code_tokenizer.eos_token_id )# 代码生成函数defgenerate_code(prompt, language="python"):# 格式化 prompt(适配 CodeLlama 指令格式) formatted_prompt =f"""<s>[INST] 请生成 {language} 代码,满足以下需求: {prompt} 要求: 1. 代码语法正确,可直接运行; 2. 包含必要的注释,便于理解; 3. 处理常见异常情况。 [/INST] """# 生成代码 outputs = code_generator(formatted_prompt) code = outputs[0]["generated_text"].split("[/INST]")[-1].strip()# 提取代码块(去除多余文本)if"```"in code: code = code.split("```")[1].strip()if code.startswith(language): code = code[len(language):].strip()return code # 测试代码生成 test_prompt ="写一个 Python 函数,计算列表中所有偶数的和,处理空列表和非整数元素的异常" python_code = generate_code(test_prompt, language="python")print("生成的 Python 代码:")print(python_code)

运行结果示例:

defsum_even_numbers(numbers):""" 计算列表中所有偶数的和 :param numbers: 包含数字的列表 :return: 所有偶数的和 """ifnotisinstance(numbers,list):raise TypeError("输入必须是列表") total =0for item in numbers:try:# 尝试将元素转换为整数 num =int(item)# 判断是否为偶数if num %2==0: total += num except(ValueError, TypeError):# 忽略非整数元素print(f"警告:元素 {item} 不是有效整数,已忽略")return total # 测试示例if __name__ =="__main__": test_list1 =[1,2,3,4,5,6]print(f"列表 {test_list1} 的偶数和:{sum_even_numbers(test_list1)}")# 输出 12 test_list2 =[]print(f"空列表的偶数和:{sum_even_numbers(test_list2)}")# 输出 0 test_list3 =[10,"abc",20,3.5,40]print(f"列表 {test_list3} 的偶数和:{sum_even_numbers(test_list3)}")# 输出 70
(2)代码修复模块
deffix_code(buggy_code, error_message=None):""" 修复有 bug 的代码 :param buggy_code: 有 bug 的代码 :param error_message: 错误信息(可选) :return: 修复后的代码 """ error_info =f"错误信息:{error_message}"if error_message else"未提供错误信息" formatted_prompt =f"""<s>[INST] 请修复以下 {language} 代码中的 bug,代码功能是计算列表中所有偶数的和: 有 bug 的代码: {buggy_code}{error_info} 要求: 1. 指出原代码的 bug 所在; 2. 生成修复后的完整代码; 3. 包含测试示例验证修复效果。 [/INST] """ outputs = code_generator(formatted_prompt) result = outputs[0]["generated_text"].split("[/INST]")[-1].strip()return result # 测试代码修复 buggy_code =""" def sum_even_numbers(numbers): total = 0 for num in numbers: if num % 2 == 0: total += num return total """ error_message ="当输入列表包含字符串元素时,会抛出 TypeError: not all arguments converted during string formatting" fixed_result = fix_code(buggy_code, error_message)print("代码修复结果:")print(fixed_result)
(3)Web 界面部署(Streamlit)

Streamlit 是快速构建数据应用的 Python 框架,适合快速部署代码生成助手的 Web 界面:

# 安装 Streamlit:pip3 install streamlitimport streamlit as st # 设置页面标题 st.title("代码生成助手")# 侧边栏配置 st.sidebar.title("配置选项") language = st.sidebar.selectbox("编程语言",["python","java","javascript","c++"]) function_type = st.sidebar.radio("功能类型",["代码生成","代码修复","代码解释"])# 主界面输入if function_type =="代码生成": prompt = st.text_area("请输入代码需求描述", height=200)if st.button("生成代码"):with st.spinner("正在生成代码..."): code = generate_code(prompt, language) st.subheader("生成的代码") st.code(code, language=language)elif function_type =="代码修复": buggy_code = st.text_area("请输入有 bug 的代码", height=200) error_message = st.text_input("请输入错误信息(可选)")if st.button("修复代码"):with st.spinner("正在修复代码..."): fixed_result = fix_code(buggy_code, error_message) st.subheader("修复结果") st.markdown(fixed_result)elif function_type =="代码解释": code = st.text_area("请输入需要解释的代码", height=200)if st.button("解释代码"):with st.spinner("正在解释代码..."):# 复用代码生成模型进行解释 explanation = generate_code(f"解释以下 {language} 代码的功能、逻辑和优化建议:\n{code}", language=language) st.subheader("代码解释") st.markdown(explanation)# 运行命令:streamlit run code_assistant.py

1.5 大模型应用上线关键考量:性能、安全与迭代

大模型应用从开发完成到生产上线,还需解决性能优化、安全风控、持续迭代等关键问题,确保应用稳定、高效、安全地服务用户。

1.5.1 性能优化:降低延迟与提升吞吐量

大模型推理的性能瓶颈主要是延迟(单轮请求耗时)和吞吐量(单位时间处理请求数),需从模型、部署、工程三个层面优化。

1. 模型层面优化
  • 模型量化:使用 8bit/4bit 量化降低显存占用,提升推理速度;
  • 模型裁剪:去除模型中冗余的层或参数(如裁剪 Transformer 层数量);
  • 轻量化模型替换:用小参数量模型(如 7B/13B)替代大模型(如 70B/175B),平衡效果与性能。
2. 部署层面优化
  • 推理引擎选择:使用 TensorRT、ONNX Runtime 等推理引擎优化算子执行;
  • 批量推理:合并多个请求进行批量处理,提升吞吐量(适合高并发场景);
  • 模型并行与分布式推理:大模型部署时采用模型并行(拆分模型到多个 GPU)或分布式推理(多个 GPU 同时处理请求)。
3. 工程层面优化
  • 缓存机制:缓存高频请求的结果(如常见问题的回答),减少重复推理;
  • 异步处理:采用异步推理模式,避免请求阻塞;
  • 硬件升级:使用更高性能的 GPU(如 A100/H100)或专用 AI 芯片(如 NVIDIA Jetson、华为昇腾)。

代码示例:ONNX Runtime 加速推理

# 将 PyTorch 模型转换为 ONNX 格式,使用 ONNX Runtime 推理import torch from transformers import AutoModelForCausalLM, AutoTokenizer import onnxruntime as ort # 导出 ONNX 模型defexport_model_to_onnx(model_name, onnx_path): tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, device_map="cpu", torch_dtype=torch.float16 )# 虚拟输入 dummy_input = tokenizer("测试输入", return_tensors="pt")# 导出 ONNX torch.onnx.export( model,(dummy_input["input_ids"], dummy_input["attention_mask"]), onnx_path, input_names=["input_ids","attention_mask"], output_names=["logits"], dynamic_axes={"input_ids":{0:"batch_size",1:"seq_len"},"attention_mask":{0:"batch_size",1:"seq_len"},"logits":{0:"batch_size",1:"seq_len"}}, opset_version=14)print(f"ONNX 模型导出成功:{onnx_path}")# 用 ONNX Runtime 推理defonnx_inference(onnx_path, tokenizer, prompt): inputs = tokenizer(prompt, return_tensors="np")# 初始化 ONNX Runtime 会话 session = ort.InferenceSession( onnx_path, providers=["CUDAExecutionProvider","CPUExecutionProvider"])# 推理 outputs = session.run(None,{"input_ids": inputs["input_ids"],"attention_mask": inputs["attention_mask"]})# 解码输出 logits = torch.tensor(outputs[0]) generated_ids = torch.argmax(logits, dim=-1) answer = tokenizer.decode(generated_ids[0], skip_special_tokens=True)return answer # 测试 ONNX 推理 export_model_to_onnx("./llama3-8b-company-qa-quantized","llama3_qa.onnx") tokenizer = AutoTokenizer.from_pretrained("./llama3-8b-company-qa-quantized") answer = onnx_inference("llama3_qa.onnx", tokenizer,"报销需要提交哪些材料?")print(f"ONNX Runtime 推理结果:{answer}")

1.5.2 安全与合规:防范生成式 AI 风险

大模型生成内容存在虚假信息、偏见歧视、隐私泄露、恶意内容等风险,需建立全流程安全风控机制。

1. 输入过滤
  • 关键词过滤:过滤包含恶意请求、敏感信息的输入(如暴力、色情、个人隐私数据);
  • 输入长度限制:防止超长输入导致的资源耗尽攻击。
2. 输出审核
  • 内容审核模型:使用专门的内容审核模型(如百度 AI 内容审核、阿里云内容安全)检测生成内容是否合规;
  • 事实核查:对涉及事实性的生成内容(如新闻、数据)进行事实核查,避免虚假信息;
  • 水印添加:为生成的文本、图像添加隐形水印,便于溯源。
3. 隐私保护
  • 数据脱敏:微调数据中去除个人隐私信息(姓名、手机号、身份证号);
  • 模型隔离:敏感场景(如金融、医疗)使用私有化部署,避免数据外泄;
  • 权限控制:对大模型应用设置访问权限,仅授权用户可使用。

代码示例:输入输出过滤

# 输入过滤函数deffilter_input(user_input):# 敏感关键词列表(可扩展) sensitive_keywords =["暴力","色情","恐怖","身份证","手机号","银行卡"]for keyword in sensitive_keywords:if keyword in user_input:returnFalse,f"输入包含敏感信息 '{keyword}',请更换输入内容"# 输入长度限制(最大 500 字符)iflen(user_input)>500:returnFalse,"输入长度超过限制,请精简至 500 字符以内"returnTrue, user_input # 输出审核函数(调用第三方 API 示例)import requests defaudit_output(generated_text):# 模拟调用内容审核 API audit_url ="https://api.example.com/content-audit" headers ={"Authorization":"Bearer YOUR_API_KEY"} data ={"text": generated_text}try: response = requests.post(audit_url, json=data, headers=headers) result = response.json()if result["status"]=="pass":returnTrue, generated_text else:returnFalse,"生成内容包含不合规信息,已拒绝展示"except Exception as e:# 审核 API 异常时,返回默认提示returnFalse,"内容审核服务异常,请稍后再试"# 集成到问答系统defsafe_qa(question):# 输入过滤 input_valid, input_msg = filter_input(question)ifnot input_valid:return input_msg # 执行推理 answer, sources = ask_qa_system(question)# 输出审核 output_valid, output_msg = audit_output(answer)return output_msg if output_valid else output_msg 

1.5.3 持续迭代:基于用户反馈优化模型

大模型应用上线后,需建立基于用户反馈的持续迭代机制,不断提升应用效果。

1. 反馈收集
  • 显式反馈:在应用界面添加"有用/没用"按钮、评分功能、用户留言区,收集用户对回答的评价;
  • 隐式反馈:监控用户行为数据(如回答查看时长、是否继续提问、是否转接人工),间接判断回答质量。
2. 迭代优化
  • 数据迭代:将用户反馈的优质问答对加入微调数据集,定期重新微调模型;
  • prompt 优化:根据用户反馈调整 prompt 模板,提升模型响应的准确性和相关性;
  • 功能迭代:新增用户需求频繁的功能(如多语言支持、文件上传解析)。
3. 版本管理
  • 使用 MLflow、DVC 等工具跟踪模型版本、训练数据、评估指标;
  • 采用灰度发布策略,新模型先服务部分用户,验证效果后再全量上线;
  • 建立回滚机制,若新模型效果不佳,可快速切换回旧版本。

1.6 本章总结与实战建议

1.6.1 核心知识点总结

💡 大模型应用开发的核心是"场景适配",需根据业务需求选择合适的模型、框架和技术方案(微调或 RAG);
💡 QLoRA 是性价比最高的微调技术,适合消费级 GPU 开发,能够快速适配私有数据;
💡 RAG 技术无需微调即可让大模型利用私有知识库,是企业级应用的首选方案;
💡 大模型应用上线需兼顾性能(延迟、吞吐量)、安全(内容合规、隐私保护)和迭代(用户反馈驱动),三者缺一不可。

1.6.2 实战避坑指南

⚠️ 避免盲目追求大模型:小参数量模型(7B/13B)在多数场景下效果足够,且部署成本更低;
⚠️ 重视数据质量:微调数据的质量比数量更重要,低质量数据会导致模型效果下降;
⚠️ 防范幻觉问题:大模型可能生成虚假信息,尤其是知识库问答场景,需通过 RAG 或事实核查机制验证;
⚠️ 合理设置生成参数:temperature 过高会导致生成内容杂乱,过低会导致内容僵化,需根据场景调整(如问答场景 0.3-0.5,创作场景 0.7-0.9);
⚠️ 提前规划硬件资源:私有化部署前需测试模型的显存占用和推理速度,确保硬件满足需求。

1.6.3 进阶学习方向

  • 大模型对齐技术:学习 RLHF(基于人类反馈的强化学习),让模型生成内容更符合人类偏好;
  • 多模态大模型应用:探索文本、图像、语音多模态融合应用(如图文生成、语音助手);
  • 大模型 Agent:学习 Agent 框架(如 AutoGPT、LangGraph),构建能够自主完成复杂任务的智能体;
  • 大模型压缩与部署:深入学习模型量化、剪枝、蒸馏技术,以及 Kubernetes 容器化部署、弹性伸缩等工程化能力。

通过本章的学习,读者已掌握大模型应用开发的核心技术和实战流程。在实际项目中,需结合业务场景灵活选择技术方案,优先通过 RAG 快速验证需求,再通过微调进一步提升效果,最终实现"技术适配业务、产品创造价值"的目标。

Read more

基于探索C++特殊容器类型:容器适配器+底层实现原理

基于探索C++特殊容器类型:容器适配器+底层实现原理

前引:容器适配器(Container Adapters)是C++标准库提供的一些特殊容器,它们基于已有的顺序容器(如vector、deque、list)实现,但提供了不同的接口以满足特定的数据结构需求。容器适配器只提供特定操作,隐藏了底层容器的部分功能。主要有三种:stack(栈)、queue(队列)和priority_queue(优先队列) ,我们一起来看看吧! 目录 适配器介绍 三大容器适配器 特性讲解 stack的底层实现 类模板定义 入栈 出栈 获取栈顶元素 判断栈空 获取栈元素 效果展示 queue的底层实现 类模板定义 入队列 获取队头元素 获取队尾元素 出队列 获取队列元素个数 判断队空 效果展示 适配器介绍 容器适配器是C++标准库提供的特殊容器类型,它们基于现有顺序容器实现,但提供受限接口和特定行为。它们不是完整的容器,

By Ne0inhk
Re:从零开始的 C++ 入門篇(五)类和对象·第二篇:构造函数与析构函数

Re:从零开始的 C++ 入門篇(五)类和对象·第二篇:构造函数与析构函数

◆ 博主名称: 晓此方-ZEEKLOG博客 大家好,欢迎来到晓此方的博客。 ⭐️C++系列个人专栏: 此方带你玩转C++_晓此方的博客-ZEEKLOG博客  ⭐️踏破千山志未空,拨开云雾见晴虹。 人生何必叹萧瑟,心在凌霄第一峰 0.1概述&前言         从本文会开始,此方会为大家带来类的默认成员函数的内容。该方面是C/C++类和对象篇章最难以理解的部分,构造函数和析构函数分别取代了C语言的Init函数和destory函数,大大提升了运行效率。默认成员函数的学习将为后续内容打下深厚的基础,本文讲解深入骨髓,细节无微不至,希望看完后能让你对这两者有深入的认识。 一,类的默认成员函数 定义:      默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。 一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数:        需要注意的是这6个中最重要的是前4个。最后两个取地址重载不重要,我们稍微了解一下即可。其次就是C++11以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们后面再讲解。默认成员函数很重要,也比较复杂

By Ne0inhk
C++:set/multiset和map/multimap文档详细解析

C++:set/multiset和map/multimap文档详细解析

Hello大家好! 很高兴与大家见面! 给生活添点快乐,开始今天的编程之路。 我的博客:<但愿. 我的专栏:C语言、题目精讲、算法与数据结构、C++ 欢迎点赞,关注 目录   前言   一 容器的分类(根据容器中各个数据之间的关系)          1.1序列式容器                  1.1.1序列式容器的概念                  1.1.2序列式容器的例子           1.2关联式容器                  1.2.1关联式容器的概念                  1.2.2关联式容器的例子   二  set/multiset           2.1参考文档(multiset包在set中所以其没有头文件)           2.2set类的介绍                   2.2.1set类的实现的简单介绍                  2.2.2set类的接口介绍                           2.

By Ne0inhk
C++/数据结构:哈希表知识点

C++/数据结构:哈希表知识点

目录 哈希表 理解哈希表 哈希值(整形) BKDR哈希   异或组合  hash_combine 哈希函数 直接定址法 除留余数法 平方取中法 基数转换法 哈希冲突 开放定址法 哈希桶 unordered_map和unorder_set如何共用一个哈希桶模板类 stl的哈希桶中Insert如何得到的键值 键为自定义类型的处理         前言:本篇文章前半部分内容为哈希表的原理, 从上到下按照理解链逐层递进。 最后三个小标题占了比较大的篇幅, 是结合c++代码来叙述, 主要内容为stl中的哈希桶如何封装的。 如果有错误的地方, 欢迎友友们指正哦。         ps:本篇文章一直到哈希桶,除了最后三个小标题,c++和java的同学都可以看, 讲的是数据结构, 即便有c++代码也很简单哦。 哈希表         首先要理解哈希和哈希表有什么不同。 哈希就是映射, 是一种算法思想。 哈希表就是映射表, 是利用映射这种思想写出的一种数据结构。          所有的哈希表的算法流程都是类似的——拿到一个key, 利用哈希函数进行hash

By Ne0inhk