十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

大模型训练全流程与数据存储方案:从微调到向量数据库的实践指南

大模型训练全流程与数据存储方案:从微调到向量数据库的实践指南 大模型学习笔记模型怎么练出来、数据怎么存起来说实话后台经常收到类似“大模型怎么训练”“本地部署用啥方案”“数据到底怎么存”的问题问的人从刚入门的学生到做了几年后端想转AI方向的工程师都有。这个标题——“模型怎么练出来、数据怎么存起来”——其实正好戳中了大多数初学者最困惑的两个点一是对大模型训练流程只有模糊概念二是对训练过程中产生的海量数据到底怎么管理完全没有认知。我最早接触大模型训练时也踩过不少坑后来把整个流程从头到尾捋过一遍才发现这东西并没有想象中那么玄乎模型训练就是一个“数据进、参数出”的迭代过程而数据存储则是保证这个流程能跑通的地基。这篇文章我就用自己实际跑过项目的经验把这两块讲透包括训练各阶段在干嘛、数据用什么格式存、怎么选存储方案以及新手最容易忽视的几个细节。1. 内容整体设计与思路拆解1.1 看懂模型训练的三要素数据、算力、算法先说一个很多教程不会直接点破的事实训练一个大模型本质上是三样东西在博弈——数据、算力和算法。三者缺一不可但很多新手只看算法忽略数据和算力结果就是照着开源代码抄了一遍发现根本跑不动或者跑出来了效果稀烂。数据决定了模型能学到什么。你给模型喂代码它就懂代码喂医疗文本它就懂医疗术语。数据质量不高模型再大也是事倍功半。业内有个说法叫“garbage in garbage out”翻译过来就是“垃圾进、垃圾出”话糙理不糙。算力决定了你能训练多大的模型。模型参数越多需要的显存和计算量就越大。比如一个7B模型约70亿参数用fp16精度做全量微调光模型本身就需要约14GB显存加上优化器状态、梯度等实际需要接近上百GB显存。这就是为什么很多人在单张消费级显卡上根本跑不动大模型微调并不是代码写得有问题而是硬件上限摆在那里。算法决定了模型能不能学得好。包括你选的模型架构Transformer是当前主流、训练策略是继续预训练还是指令微调、超参数学习率、batch size等每一项都直接影响收敛效果。我的建议是新手不要一开始就追求搞个大模型全流程训练先把这三要素的关系捋清楚后面所有环节都会顺很多。1.2 要“从零训练”还是“微调”真正动过手的人都知道从零训练一个大模型在绝大多数场景下既没必要也不现实。所谓“从零训练”是指用随机初始化的参数在海量原始文本上从头做预训练。这个过程的成本极高业界公认的数据是训练一个千亿参数模型需要数千张高端GPU跑几个月电费、硬件折旧、人力成本加起来轻松过千万。个人开发者或者中小企业基本不用考虑这条路。更现实的做法是“微调”拿一个已经预训练好的开源模型底座比如Llama、Qwen、ChatGLM等在自己的领域数据上继续训练让模型“适应”你的任务。微调分两种主流方式全量微调Full Fine-tuning所有参数都参与训练效果最好但显存开销巨大。参数高效微调PEFT只训练一小部分参数比如LoRA、QLoRA这是目前个人开发者和中小团队最常用的方案。一张24GB显存的显卡就能微调7B模型门槛降低了很多。我的学习路线建议是先学会微调理解数据和模型的关系再逐步去了解预训练的原理。这样既能把成本控制在可接受范围内也能真正理解整个训练体系。回到这个标题本身不管是预训练还是微调背后都绕不开两个问题数据怎么组织、怎么存。下面我分别拆开讲。2. 核心拆解模型训练全流程到底经历了什么2.1 从预训练到微调模型训练的完整链路我画一张“地图”给大家建立整体认知。一个模型从“零”到真正能用一般经历这么几个阶段第一阶段预训练Pre-training这是“大规模读书”阶段。模型在海量文本上通过自监督学习掌握语言规律核心任务是“预测下一个词”。这一步训练出来的模型叫基座模型Base Model特点是知识面广但不会聊天、不会Follow指令。比如Llama系列原版就属于这类你和它说“你好”它可能回你一段不知道哪来的文本。第二阶段监督微调SFTSupervised Fine-tuning这是“学规矩”阶段。我们整理一批“问题-标准答案”对让基座模型学会按照人类期望的方式回答问题。经过这一步模型才具备“对话感”。很多中文开源模型比如Qwen系列就是在基座模型基础上做了大规模SFT。第三阶段对齐Alignment这一步让模型回答更符合人类偏好常见方法有RLHF基于人类反馈的强化学习和DPO直接偏好优化。简单说就是让模型在多个答案中学会选那个“人类更喜欢”的。这个阶段技术门槛和成本都更高普通开发者接触到的不多但理解它的存在很重要。第四阶段部署和推理Inference训练完成后模型需要被部署到服务上通过API或本地工具对外提供服务。这个阶段做的是量化、推理加速、服务编排等工程工作。从上面的链路能看出来“模型怎么练出来”不是一次性的操作而是一条从数据到模型再到服务的流水线。每一步都要处理大量数据也就引出了“数据怎么存起来”的问题。2.2 数据清洗训练前最容易翻车的环节说到数据我必须单独把清洗拎出来讲。因为这是大多数人最不重视、但翻车概率最高的环节。我最早做微调的时候直接拿网上爬来的数据去训结果模型学了一堆乱码和重复文本生成的东西根本没法看。后来仔细排查才发现语料里混了大量HTML标签、特殊符号和重复段落模型把这些噪声也当成了“规律”。实践中数据清洗至少要做这几步去重重复文本会让模型过度学习某些片段影响泛化能力。可以用MinHash算法对大规模文本做近似去重。过滤过滤掉过短、过长、包含特殊字符或者明显是垃圾内容的数据。规则可以很简单比如判断文本长度、URL占比、乱码比例等。格式化统一编码、统一标点、去除不可见字符。中英文混排时尤其要注意空格和换行的处理。隐私和安全过滤去掉个人敏感信息、有害内容等。这一块不只是合规要求也是模型质量的基本保障。很多教程只会告诉你“清洗数据很重要”但不告诉你清洗要花掉整个项目大约40%-60%的时间。这是行业普遍的现状不用觉得是自己效率低。做好心理预期后面遇到“卡在数据处理上”就不会慌。2.3 训练数据的组织格式JSONL、Parquet 还是 Arrow聊完清洗再聊存储格式。这可能是“数据怎么存起来”这个问题最核心的部分了。很多新手一上来就想到MySQL、MongoDB这种传统数据库但说实话训练场景下关系型数据库并不是主力原因后面会讲。先看看几个主流的训练数据格式JSONL每一行是一个独立的JSON对象格式灵活、可读性好处理单个样本特别方便。SFT阶段的数据集基本都用这种格式一条数据大概长这样{instruction: 解释一下什么是机器学习, output: 机器学习是一门研究如何让计算机从数据中自动学习和改进的学科。} {instruction: 写一首关于秋天的诗, output: 秋风起落叶黄稻浪翻金遍地香。}JSONL的优点是修改方便可以逐行读取内存占用低非常适合处理上百万条训练样本。缺点是没有压缩文件体积大而且没有结构化索引不适合做复杂查询。Parquet列式存储格式压缩率高、I/O效率好在大规模数据集上性能碾压JSONL。一般预训练阶段处理TB甚至PB级语料时用Parquet几乎是标配。但它的缺点是二进制格式可读性差调试不方便。Arrow内存列式格式主要用在需要高性能数据交换的场景。比如用Ray或者Dask做分布式数据处理时Arrow是中间数据的默认格式。它的特点是“零拷贝”访问但持久化存储用得相对少。做个简单对比格式优点缺点适用场景JSONL可读性好、逐行处理、上手快文件大、无索引、性能一般SFT数据集、小规模实验Parquet高压缩、列式读取快二进制不可读、调试不便大规模预训练语料Arrow高效内存交换、零拷贝持久化场景支持一般分布式训练中间数据我的经验是小项目用JSONL起步数据量大了再迁到Parquet。没必要一上来就上重武器但也不能一直用JSONL硬扛百万条以上数据的读取速度差距会非常明显。3. 实操过程与核心环节实现3.1 本地微调一个7B模型从数据准备到模型输出光讲概念没意思我直接拿一个实际的小项目来演示在单张24GB显存显卡上微调一个7B对话模型让它学会我们定制的话术风格。步骤一准备训练数据假设我们要做一个客服机器人让它说话更专业、更礼貌。那就先整理一批历史客服对话转成SFT需要的三段式格式{instruction: 用户我的订单三天了还没发货怎么回事, input: , output: 您好非常抱歉让您久等了我这边立即为您查询订单物流状态请稍等片刻。} {instruction: 用户这个商品可以退换吗, input: , output: 您好自签收之日起7天内在商品不影响二次销售的情况下可以申请无理由退换货。}把几千条这样的数据放到一个train.jsonl文件里同时准备一个dev.jsonl做验证集。步骤二加载模型和分词器这里我以ChatGLM3-6B为例其他模型如Qwen、Llama也类似用HuggingFace的transformers库加载from transformers import AutoModelForCausalLM, AutoTokenizer model_path THUDM/chatglm3-6b tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_path, trust_remote_codeTrue, torch_dtypetorch.float16, device_mapauto )注意几个关键点trust_remote_codeTrue是ChatGLM系列必须要开的torch_dtypetorch.float16能大幅节省显存device_mapauto让框架自动分配GPU和CPU资源。如果显存不够还可以加一个load_in_8bitTrue或load_in_4bitTrue做量化加载。步骤三用LoRA微调LoRA的原理是冻结原始模型参数只训练一小部分低秩矩阵训练参数量通常只有总参数的1%不到。用peft库很容易实现from peft import LoraConfig, get_peft_model lora_config LoraConfig( r8, lora_alpha32, lora_dropout0.1, target_modules[query_key_value], ) model get_peft_model(model, lora_config) model.print_trainable_parameters()r8是LoRA的秩秩越大可学习的参数越多效果可能更好但显存开销也更大lora_alpha是缩放系数一般设为r的2到4倍target_modules指定要对哪些模块做LoRAChatGLM系列是query_key_valueLlama系列则是q_proj和v_proj。步骤四配置训练参数并开始训练from transformers import Trainer, TrainingArguments training_args TrainingArguments( output_dir./chatglm3_qa_lora, per_device_train_batch_size4, gradient_accumulation_steps8, learning_rate2e-4, num_train_epochs3, logging_steps50, save_steps500, warmup_steps100, fp16True, ) trainer Trainer( modelmodel, argstraining_args, train_datasettrain_dataset, eval_datasetdev_dataset, tokenizertokenizer, ) trainer.train()这里有几个参数值得解释一下gradient_accumulation_steps8表示每8个step做一次参数更新这相当于把batch size从4放大到32的效果但显存只付了4的代价是单卡训练最实用的技巧之一fp16True是混合精度训练能减少约40%的显存占用。步骤五保存合并模型LoRA训练完保存的是一层“补丁”需要把它和原始模型合并才能用在常规推理流程里model.save_pretrained(./chatglm3_qa_lora) merged_model model.merge_and_unload() merged_model.save_pretrained(./chatglm3_qa_full)到这里“模型怎么练出来”这个问题的实操闭环就走通了。整个流程跑下来如果数据量在几千条级别单卡24GB显存大概需要几小时。3.2 数据持久化训练数据集应该怎么组织存放模型练出来的同时我会顺手把整个项目的数据目录规范好。这块儿很多人不重视等到项目迭代了几轮数据集改了一版又一版才发现根本分不清哪个是最终版哪个是过期版。我自己的项目目录通常是这样的project/ ├── data/ │ ├── raw/ # 爬虫/导出的原始数据只读不修改 │ ├── processed/ # 清洗后可直接用于训练的数据 │ ├── jsonl/ │ │ ├── train.jsonl │ │ └── dev.jsonl │ └── parquet/ # 大规模数据的转换格式 ├── models/ │ ├── base/ # 预训练权重 │ └── finetuned/ # 微调产物 │ ├── checkpoint-500/ │ └── checkpoint-1000/ ├── scripts/ │ ├── clean_data.py │ ├── train.py │ └── eval.py └── logs/几个原则raw目录下的原始数据永远不修改每次清洗都生成新的processed文件这样可以追溯“模型效果变差是不是因为数据改动”。checkpoint不要只保留最后一个至少保留loss最低的那个。因为训练后期可能过拟合不一定最后的checkpoint就是最好的。每个数据集文件加版本号或日期后缀比如train_v2_0620.jsonl比都叫train.jsonl要省心得多。3.3 向量数据库让“长期记忆”真正可被检索训练只是“记到参数里”但有些知识不适合烧进训练成本里尤其是需要频繁更新的私有知识。这时候就需要“检索增强生成RAG”而RAG的地基就是向量数据库。理解向量数据库并不难。你把一段文本用嵌入模型转换成一串几百维的浮点数向量向量在空间里的位置就代表了语义。语义相近的文本向量距离就近。查询的时候把用户的问题也转成向量然后在数据库里找最近的K个向量把这K个向量对应的原文丢给大模型做参考。这就是RAG的完整链路。选型上我实际用过的几个Chroma轻量级pip安装就能跑适合个人项目和快速原型。FAISSMeta开源的向量检索库性能很强需要自己管理索引和持久化。Milvus分布式向量数据库适合生产级、海量数据的场景部署稍重。QdrantRust写的性能和易用性平衡得好Docker一键启动是我目前用得最多的。如果你只是本地搞个知识库问答Chroma完全够用如果数据量到百万级向量以上再考虑Milvus或者Qdrant。存储上的核心建议向量数据库不要存所有字段只存向量和ID原始文本放对象存储或者文件系统里。原因一是向量数据库的存储成本比普通文件高很多二是原始文本更新频繁把它和向量索引解耦后重新建索引的成本会低很多。3.4 用传统数据库存什么元数据与训练日志虽然训练任务本身不是传统关系型数据库的主场但项目运营离不开MySQL这类工具。我在实际工作中主要用MySQL存这几类数据数据集的元数据数据来源、采集时间、清洗规则、样本数量、质量评分。方便复盘“这个模型为什么训得好”。训练实验记录每次训练的模型版本、训练参数、loss曲线、评测指标。方便对比实验。标注任务数据人工标注的任务、标注结果、审核状态。用MySQL存元数据的好处是查询方便写两行SQL就能统计出“哪些清洗规则下样本质量最高”这种横向对比对数据迭代的指导意义非常大。至于“MySQL查看数据存储路径”这种运维问题其实和模型训练没有直接关系数据库引擎自有自己的存储目录和表空间管理方式不需要把数据文件直接暴露给训练系统。训练读数据走API不直接碰数据库文件这个边界要清晰。4. 常见问题与排查技巧实录4.1 显存溢出新手最常见的报错训练时最常遇到的报错就是CUDA out of memory。第一次遇到别慌按这几个顺序排查降低batch size这是最直接的方法。从4降到2或1显存立刻释放。代价是训练速度变慢配合梯度累积可以弥补。开启梯度检查点gradient checkpointing用时间换空间训练速度会慢20%~30%但显存占用能降低约60%。在transformers里一行代码搞定model.gradient_checkpointing_enable()。降低输入序列长度对大多数微调任务来说最长序列不是越长越好。把max_seq_length从2048砍到1024显存占用会显著下降。前提是训练数据的实际长度大部分在1024以内。检查显存碎片有时候不是真的不够而是卡上的显存被碎片化了。加一行torch.cuda.empty_cache()或者换个更大的batch size反而能跑通这种情况我也遇到过。换量化加载用4bit量化加载模型7B模型显存占用能降到6GB左右消费级显卡也能跑微调。4.2 Loss不降或乱跳Loss一直是3.0上下浮动几轮训练都不下降大概率是学习率设置不对。CLM训练常见的学习率范围是1e-5到5e-5全量微调或1e-4到5e-4LoRA如果设成1e-3以上很容易发散。Loss直接崩到负数或者NaN一般有两个原因一是训练数据里有脏数据比如超长文本、乱码字符、空行预处理时没过滤干净二是fp16混合精度下数值溢出可以尝试加上tf32TrueA100及以上显卡支持或者换bf16。4.3 模型训练完生成效果差训练跑完了loss也降了但生成结果就是不对味。这时候先别急着调参按这个顺序排查第一看验证集效果。训练集loss低但验证集loss高说明过拟合了需要加点正则化、增大数据量或者提前停止。两个都低但生成效果差说明评测方式有问题输出解析的prompt格式可能和训练时不匹配。第二检查数据格式。SFT时instruction、input、output三个字段的顺序和分隔符必须保持一致有个小细节是很多模型的官方模板里input为空时训练脚本是否仍然拼接了多余的字段这会导致模型学到了错误的模式。第三温度和采样参数。有些模型部署时默认温度太高导致输出发散。推理时temperature0.7和top_p0.9是比较通用稳妥的起始值。4.4 本地部署大模型时的显存与速度权衡训练完的模型要落地使用最常见的方式是在本地部署。选推理框架前先搞清楚自己的核心诉求是显存不够要极致压缩还是速度优先要求极限吞吐。Ollama新手最友好的本地部署工具一条命令装好模型自动做量化和管理。适合个人使用和快速验证但功能和性能调优空间有限。网上常有人问“Ollama怎么把模型安装到D盘”本质是模型下载路径默认在C盘用户目录在启动服务前设置OLLAMA_MODELS环境变量指向D盘目标目录即可装完记得重启服务。vLLM生产级推理引擎核心优势是PagedAttention技术显存利用率大幅提升吞吐量比原生transformers快好几倍。适合并发量较大的场景。它对显存的需求也比较高7B模型建议至少16GB显存。llama.cpp纯CPU也能跑推理量化支持非常完善。没有GPU的笔记本也能体验大模型速度慢一点但可用。我个人的选择规律是个人尝鲜用Ollama内部系统接API用vLLM服务器没有GPU备用方案用llama.cpp。两个都试过之后你自然能感受到它们在显存策略上的本质区别。4.5 “任何模型都能在我的本地设备上训练吗”这是被问得最多的问题答案是不能。能不能训练取决于三个硬指标显存大小、内存大小、计算能力。对于普通显卡8GB~16GB显存微调1B~3B的小模型是可行的对于专业卡或高端消费卡24GB~48GB显存7B~13B模型的LoRA微调没问题如果在云上租用A100/H100这类80GB显存的卡70B模型也能微调。模型和数据都是可以压缩和量化的但硬件的物理上限没法突破。如果硬件条件有限还有两个替代思路一是用云服务商的免费或低成本GPU实例做短期训练二是用参数高效微调并搭配更小的基座模型比如0.5B、1.5B的模型在普通笔记本上也能跑起来。5. 不同场景下的数据存储选型建议5.1 个人学习实验场景个人电脑上做实验最实用的存储方案就是本地文件系统加轻量向量库。数据规模一般在几十GB以内JSONL文件直接扔在硬盘上完全够用。向量检索用Chroma或者FAISS本地模式不需要搭服务。要注意的是个人电脑的磁盘空间管理。模型文件很占空间一个7B模型fp16精度大约14GB4bit量化约4GB加上数据集、日志几个项目下来几百GB就没了。建议用外置SSD存储不常用的模型权重只在跑训练时挂载。5.2 团队协作与生产环境涉及多人协作和数据管理规范时建立数据分层机制变得很重要。我参与过的团队里数据一般分三层数据湖/原始层存放所有原始采集数据不要求结构化重在“存得住”。数据仓库/特征层经过清洗转换按主题组织直接用SQL就能查到干净数据。专用存储/训练层按训练任务打包直接喂给训练脚本。生产环境中原始数据一般放在对象存储里比如MinIO版本管理用DVCData Version Control向量检索用单独的向量数据库服务。训练脚本通过API或SDK拉取数据而不是直接读数据库表。这套架构和“直接向某数据存储区远程传文件”这种操作完全是两个思路。远程传文件是运维层面的事情可以走SCP、SFTP或者挂载网络盘但训练系统不会依赖这种手工方式而是走自动化的数据管线。5.3 成本控制视角的存储方案对比数据存储这块我在不同预算下做过对比表分享出来供参考方案优点缺点推荐场景本地磁盘零额外成本、读写快容量有限、无备份个人实验单机外接SSD便携、容量可控有损坏风险个人小团队NAS多设备共享、RAID备份读写速度一般团队协作对象存储容量无限、高可靠按量计费、延迟较高生产环境一个容易被忽视的成本陷阱是对象存储的流量费往往比存储费高。训练时如果反复从对象存储拉取数据网络流量费用可能比存储本身贵很多。解决办法是把常用数据缓存到本地或集群分布式文件系统只把冷数据放对象存储。6. 学习路径与资源避坑指南6.1 大模型学习的推荐路线这段时间后台不断有人问“大模型学习路线”我推荐一条自己验证过的路径尤其适合有编程基础但AI领域是零基础的人第一步了解Transformer架构和注意力机制。不需要抠数学公式但至少要明白“词嵌入-多头注意力-前馈网络”这个基本骨架。推荐Karpathy的《Lets build GPT》视频手把手教你从零写一个GPT。第二步跑通HuggingFace的transformers库基础流程。load模型、做推理、写prompt先感受模型怎么工作。第三步做一次LoRA微调。找个小数据集微调一个小模型完整跑一遍训练和推理。这一步对理解全文内容最有帮助。第四步做一次RAG项目。本地搭一个知识库问答理解向量化和检索流程。第五步系统地看深度学习理论比如吴恩达的《Deep Learning Specialization》。第六步深入源码和数据工程看数据怎么清洗、怎么管、怎么优化。这条路线前四步基本都是在动手后两步是补理论。理论和实践交替进行比上来就啃《深度学习》厚的教材效率高得多。6.2 模型下载与新模型追踪国内用户下载开源模型主流渠道是ModelScope魔搭社区和HuggingFace。两者的模型大多互通ModelScope在国内访问速度快很多我优先推荐。在ModelScope上下载模型用它的官方SDK一行命令就能拉下来还能断点续传from modelscope import snapshot_download model_dir snapshot_download(Qwen/Qwen2.5-7B-Instruct)唯一要注意的是模型更新迭代很快比如Qwen系列前脚刚出Qwen2后脚Qwen2.5就来了。我的经验是关注star数高、有活跃社区的模型而不是追最新版本经过了社区验证的模型踩坑风险小很多。想追踪新模型动态建议在HuggingFace上关注Trending榜单在X上关注几个头部AI实验室账号再订阅几个中文AI社区的资讯频道就够了没必要每天刷几十个群。7. 最后说点我自己的实在体会做模型训练和数据存储这件事时间久了你会发现真正能决定项目成败的往往不是那些炫酷的算法技巧而是这些“脏活累活”数据管理这件事做得好的团队和做得差的团队差距一开始看起来不大模型效果可能也就差几个点。但等到你要排查问题、追溯某个bad case是哪一批数据导致的、要对比多个实验版本时一个干净、有版本、有记录的数据管理系统能救命。我的项目里但凡遇到“模型效果回退又找不到原因”的九成都是数据没管好。给新手的建议也很简单一个小项目把数据格式从JSONL换成Parquet把训练脚本的checkpoint目录按时间排好把数据集的版本号写清楚这些加起来也就是一天的功夫但能让你接下来一个月都不用来回折腾。模型训练是个复杂的系统工程但也没必要望而生畏。从一次小小的LoRA微调开始维护好第一批训练数据你会很快理解整个流程的精髓——数据是燃料模型是发动机存储系统就是油箱。三者配合好整个系统才能跑得动、跑得久。最后再分享一个小技巧训练脚本里务必加上logging_steps参数把loss日志输出到文件里。很多新手只是在控制台看两眼loss就完事儿了等到后面想复盘某个checkpoint是在什么状态下保存的才发现什么都没留下来。训练过程中顺手在日志文件里记全批次号、学习率、显存占用这些信息成本极低但复现实验结果时它是无价之宝。
返回列表