多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

基于Ziya-LLaMA-13B的中医古籍问答模型微调实战

基于Ziya-LLaMA-13B的中医古籍问答模型微调实战 简介本资源是面向人工智能与自然语言处理领域研究者及中医信息化开发者的大模型应用实践项目聚焦中医古籍知识的结构化理解与问答生成。基于Ziya-LLaMA-13B-V1开源基座模型通过监督微调SFT、奖励建模RM与PPO强化学习等完整训练流程构建了专注《黄帝内经》等典籍的垂直领域问答模型——黄帝Huang-Di模型仓库。压缩包共54个文件含22个核心Python训练/推理脚本如train_sft.py、cli_demo.py、web_demo.py、5个Shell自动化脚本覆盖古籍预训练、评估与部署、2个YAML配置文件及配套工具模块整体仅150KB轻量但结构完整便于快速复现与二次开发。目前已有669人学习下载提供从数据预处理、模型导出到CLI/Web/API多端交互的全链路代码支持特别适合需在医疗垂域落地大模型技术的工程师与科研人员参考实践。 整理个人模型仓库时翻到黄帝(Huang-Di)模型仓库.zip这个名字第一反应是有人把中医古籍知识问答做到了开源中文大模型上。这个项目基于Ziya-LLaMA-13B-V1做指令微调目标是让模型能理解《黄帝内经》《伤寒论》这类古文原文回答症状辨证、方剂功效、治法思路等问题。我当时做它的初衷很简单通用大模型聊现代中文没问题一碰到文言文和中医术语不是答非所问就是一本正经地编造原文出处。于是干脆拉一个开源基座自己做一套完整的中医古籍问答微调流程。这篇文章把整个链路完整拆开基座为什么选它、训练数据怎么造、LoRA参数怎么定、推理部署踩了哪些坑、zip包从下载到跑起来需要几步。适合正在做垂直领域大模型微调的人参考也适合古籍数字化、医疗NLP方向的同学当案例看哪怕你刚入门大模型按这套流程走一遍也能跑出一个能用的小领域问答模型。1. 为什么是Ziya-LLaMA-13B-V1基座模型的选型逻辑1.1 中医古籍问答对基座模型提出了哪些硬要求中医古籍问答不是普通的知识问答它对基座模型的要求比想象中苛刻。首先模型要能读懂文言文。现代中文大模型训练语料里古文的占比普遍偏低尤其是带中医专业语境的文言文通用模型的理解能力很有限。其次中医有一套和日常话语差异极大的术语体系阴阳五行、气血津液、经络俞穴、八纲辨证、四气五味这些词在通用语料里出现的频次不高模型如果没有见过足够多上下文很难学到准确的语义关联。还有一个很容易被忽视的点中医问答讲究出处引用。患者问“失眠多梦、心悸盗汗怎么办”好的回答不是直接丢一个方子而是说清楚这对应《黄帝内经》或《伤寒论》里的哪一段思路再给出临床表现和方剂方向。这种“原文引用辨证分析”的输出结构对模型的长文本理解能力和忠实度要求很高。如果基座本身中文底子差微调时模型会把古文和现代白话混在一起输出看起来像文言文其实是病句堆砌。所以选基座时我给自己定了几个标准中文语料覆盖要够、词表对中文的表示效率要高、模型规模要在个人开发者的算力范围内、开源生态要成熟能跑LoRA、有大量参考案例。综合下来Ziya-LLaMA-13B-V1是当时最合适的选择。1.2 Ziya-LLaMA-13B-V1这个基座到底改了什么Ziya-LLaMA-13B-V1来自IDEA研究院的封神榜团队它做的事情可以理解为把国外开源模型拿过来针对中文语境做二次增强。原始LLaMA-13B的词表是以英文和拉丁语系为主的中文在这套词表里被切得非常碎同一个中文词经常被拆成好几个token这导致两个问题第一训练和推理效率低。同样的中文内容用原始LLaMA词表编码token数量明显偏多处理速度慢、显存占用也更高。第二模型对中文单词的“整体感”弱。词表里没有对应的中文词表项模型学习一个词需要靠多个token组合才能建立映射学得慢还容易学歪。Ziya-LLaMA把词表从原始的约3.2万扩展到接近4万补充了7000多个中文相关token然后在海量中文语料上做了继续预训练让模型先“母语化”再谈下游任务。这个版本V1是它的第一版中文增强模型虽然名字带LLaMA但实际中文理解能力比原生LLaMA-13B强不少。关键是它保留了LLaMA-13B的标准架构这意味着社区里所有成熟的微调工具HuggingFace PEFT、bitsandbytes、QLoRA都能直接拿来用不需要改底层代码。对做垂直领域模型的人来说这是个非常重要的优势。1.3 为什么不选7B也不选65B模型选型阶段我把主流开源基座都对比了一遍。7B的参数规模在消费级显卡上跑起来很轻松但问题是中医古籍知识本身覆盖范围广从基础理论到临床方剂到本草药物7B的容量塞进去会非常拥挤模型容易被训练成“背了答案但不会推理”。尤其是古文理解这种对上下文依赖很强的任务参数太少模型记不住也理解不了长文本里的复杂逻辑。65B甚至更大的模型效果肯定更好但现实问题也很明显训练至少需要多卡集群推理需要A100级别个人开发者和中小团队根本跑不动。13B是一个很好的平衡点——它有足够的知识容量可以在单张24GB显存的显卡上用QLoRA完成微调推理时用4bit量化后16GB显存的卡也能带起来。对做垂直领域模型的个人或小团队来说13B是当下最务实的黄金规模。提示选基座时别只看榜单分数要看你目标领域的语料在这个模型里的表现。我当时做了个很简单的测试拿《伤寒论》里一段原文让模型用白话复述Ziya-LLaMA-13B-V1虽然复述不完全准确但至少能识别出这是在讲六经辨证同规模的通用模型直接把它当普通文言文处理完全不涉及辨证逻辑。这个差距在微调前就存在微调只是把潜力释放出来。2. 数据是中医模型的核心古籍语料与指令数据构造2.1 中医古籍语料的特殊性做这个项目时数据准备花的时间比模型训练多得多。训练本身只有几个小时但数据清洗和指令构造前前后后忙了两周。中医古籍语料有几个非常棘手的特性第一个是断句问题。古籍原文没有现代标点全靠训练者自己断句。断句断错了语意就完全变了。比如《伤寒论》里“太阳之为病脉浮头项强痛而恶寒”断成“太阳之为病脉浮头项强痛而恶寒”这是标准断法如果断错位置整个条文的辨证逻辑就乱了。我用的是中华书局等整理出版的标点本作为底本而不是直接拿影印古籍OCR识别这一步省了很多事。第二个是繁简字和异体字。古籍原文以繁体字为主还夹杂大量异体字。直接全部转简体看似方便但在中医语境里会出问题比如“乾”干燥和“干”干预在古籍中有明确区分统一转成“干”后语义就模糊了。我做了术语表保护对涉及药名、病名、穴位的字词做映射白名单确保转换后保留原文用字习惯。第三个是版本差异。《黄帝内经》有多个版本流传不同版本的文字略有出入。训练时如果混入不同版本的同一段话模型会学到矛盾的信息。我按版本来源给每条数据打了标签同一问题尽量只喂一个版本的上下文减少干扰。2.2 指令数据格式设计与任务类型数据格式用的是Alpaca指令格式每条样本由instruction、input、output三部分组成。这套格式在开源社区验证成熟几乎所有的微调框架都支持不需要额外开发代码。设计instruction时我刻意强调了“身份任务约束”三层结构。示例{ instruction: 你是研读中医古籍的智能助手。请基于给定的古籍原文用现代白话解释症状对应证型的判断依据再给出治疗方向和方剂思路。如果原文没有明确记载请说明这一点不要编造。, input: 原文《伤寒论·辨太阳病脉证并治》\n患者症状发热恶风自汗出脉浮缓。\n请判断此为何证并说明治法。, output: 此条文记载的是太阳中风证。恶风、自汗出、脉浮缓是营卫失调的表现与太阳伤寒的无汗、脉浮紧形成对比。治法以解肌祛风、调和营卫为主方剂思路可参考桂枝汤加减。 }这里有几个设计细节值得展开说。约束部分“不要编造”很重要中医古籍里有很多内容现代医学无法验证模型如果基于训练数据里的关联去瞎编输出的方剂会带误导性。另外output里我要求先给证型判断再讲治法最后落到方剂思路这个结构化输出让模型的回答有层次而不是把所有信息混在一起。任务类型我一共设计了五种文白释义把一段古籍原文翻译成现代白话保留术语原貌原文抽取问答给定原文段落从里面抽取症状、证型、方剂的对应关系辨证推理给一组症状让模型结合所学判断证型并给出依据方剂解析围绕某个方剂解释组方原理、主治范围、加减变化、禁忌综合问答模拟患者提问模型以古籍为据给出建议并提示紧急情况就医五种任务覆盖了从“读懂原文”到“模拟应用”的完整链路。只做单一任务模型学到的能力会很窄混合任务训练模型才能建立中医知识的整体框架。2.3 数据清洗、质量筛选与数据量控制原始语料从公开渠道收集后做了四轮清洗。第一轮去重不同来源的同一古籍文本按相似度去重避免模型对重复语料过拟合。第二轮长度过滤过短的样本少于10个字符没有训练价值直接丢弃过长的样本统一切分到1024个token以内保证数据分布稳定。第三轮格式校验所有样本必须是合法的JSON格式字段完整output非空。第四轮人工抽检对自动生成的问答对进行10%抽样检查发现错误及时修正。为了让模型学到的知识是可追溯的每条样本在input中注明了古籍出处比如“《金匮要略·胸痹心痛短气病脉证治》”。模型见过大量带出处的样本后回答时也会倾向于给出参考来源这能在一定程度上缓解“知识无根”的问题。数据量方面最终训练集约1.8万条验证集约2000条测试集约1000条。这个规模不大但对垂直领域指令微调来说够用了。更大的数据量当然更好但清洗成本会成倍增加边际收益也会递减。我个人的经验是垂直领域微调5000条高质量数据基本能看出效果2万条以上才能做到覆盖主要场景10万条级别需要团队化运作。注意机器生成候选答案必须人工校验。我第一版数据里有一批用通用大模型帮忙生成的问答案例没有抽检就直接用了结果模型学到了一堆模棱两可的表述比如“可能有效”“需进一步观察”这种输出放在古籍问答里非常违和。后来全部删掉只保留从原文严格对应的问答对。3. 微调方案拆解低资源训练与参数调优细节3.1 为什么用LoRA而不是全参数微调13B模型全参数微调理论可行现实很骨感。模型权重FP16精度下约26GB再加上梯度、优化器状态训练时的显存需求超过60GB这还没算激活值。一张A100才80GB而且是单卡跑多卡还要考虑通信开销。个人开发者想复现这个项目门槛直接被抬到云端租卡甚至实验室集群。LoRA的思路完全不同。它冻结原始模型的全部权重只在每一层Transformer的注意力模块旁边加入低秩矩阵训练时只更新这些低秩矩阵。实际可训练参数量只有原模型的0.1%到1%13B模型用LoRA训练显存需求直接降到全参微调的四分之一以下。再加上4bit量化加载基座权重也就是QLoRA单张24GB显存就可以跑13B模型微调普通消费级显卡能拿下的门槛让这个项目有了可持续复现的价值。LoRA还有一个隐性优势不容易灾难性遗忘。全参微调相当于把模型重写一遍学中医古籍的同时很容易把通用能力冲掉。LoRA是在原模型能力上做适配学新知识的代价小模型既懂中医古籍也保留对话、推理等基础能力。3.2 关键训练参数的选择逻辑微调参数我用的是社区验证过的经验值再根据数据特点做了微调。先列一个完整配置参数数值说明基础模型Ziya-LLaMA-13B-V14bit量化加载LoRA秩 r16控制低秩矩阵维度LoRA alpha32缩放系数通常为r的2倍LoRA dropout0.05防止小模型过拟合学习率2e-4LoRA常用范围批次大小4单卡限制梯度累积8等效批次32最大序列长度1024覆盖大部分样本训练轮数3观察loss收敛情况保存策略每500步保存方便回溯Rank为什么取16而不是8或32Rank太小低秩矩阵表达能力不够模型学不进复杂的辨证逻辑Rank太大训练参数增多容易过拟合且收益递减。13B规模下r16是一个经过大量社区项目验证的甜点值。Alpha取32等于r的两倍让更新幅度在初始阶段稍微放大有助于训练前期快速收敛。学习率2e-4是LoRA在13B模型上的成熟经验值全参微调通常用1e-5到3e-5LoRA因为只更新少量参数可以用更大的步长。有一个容易被忽略的决策target_modules设置。默认应该覆盖q_proj和v_proj但我把k_proj和o_proj也纳入了训练。原因是中医古籍问答高度依赖上下文注意力完整训练四个投影矩阵模型对关键信息症状词、方剂名的关联捕捉能力更强。代价是训练参数量增加但13B模型仍然能扛住。3.3 显存估算和训练成本简单估算一下显存占用。QLoRA下13B权重以4bit加载约6.5GB。LoRA参数本身很小几百万到千万级别可忽略不计。主要开销在优化器状态和激活值。Adam优化器对每个可训练参数维护两份状态但可训练参数少这部分占用很低。激活值的峰值出现在反向传播阶段受最大序列长度和批次的直接影响1024长度、batch_size4激活值大约占用8GB到10GB。合起来一张24GB的RTX 4090可以稳定跑完训练。如果是16GB显存把batch_size降到2梯度累积升到16也能勉强跑。训练时间方面1.8万条样本3个epoch4090单卡大约需要5到6小时。这个成本对个人项目来说完全可以接受比租云GPU还划算。提示训练前务必先跑一个500步的小实验确认loss曲线正常下降再全量训练。我第一版跑全量时因为数据集里混入了几条超长样本max_length截断导致训练崩溃查了半天才发现是数据处理的问题。小实验能帮你提前暴露这类坑。4. 训练过程观察与效果复盘4.1 训练指标怎么看loss曲线之外更重要的事训练日志里loss曲线看起来很正常前500步从2.3快速降到1.1左右1500步之后降速放缓3000步左右进入平稳期。单看loss在验证集上的表现也不错困惑度一直在下降。但我很快发现一个现象验证loss降到底部之后训练loss还在缓慢下降这通常是过拟合的信号。于是我在第三个epoch的1200步处提前停了没让训练跑满。模型规模越大越容易在训练集上“背答案”。loss只反映模型对训练数据的拟合程度不代表它真正理解了中医辨证逻辑。我更关注的是另一组评价维度引用原文是否准确、证型判断是否有依据、方剂给出是否合理、是否混淆了不同古籍的观点。这四个维度用人工评分每类抽100条样本让三位有中医背景的朋友独立打分取平均分。最终结果原文引用准确率约82%证型判断合理率约78%方剂建议可接受率约74%跨古籍混淆率约5%。这个成绩谈不上完美但作为第一版垂直模型已经能看出数据构造的成效。最明显的短板是方剂建议部分模型偶尔会张冠李戴把《伤寒论》里的方子安到《温病条辨》的条文下这类错误在人工抽检时能发现但没办法通过训练完全消除。4.2 效果实测模型输出到底长什么样展示几个测试集上的实际输出。注意这里展示的是模型训练效果不构成医疗建议真正的中医诊疗请找专业医师第一个测试用户输入“失眠多梦心悸易醒五心烦热盗汗舌红少苔脉细数。”模型输出为“根据症状阴虚不能制阳虚热内扰心神导致失眠多梦、心悸易醒。五心烦热、盗汗、舌红少苔、脉细数均为阴虚内热之象。《素问·阴阳应象大论》提到‘阴在内阳之守也阳在外阴之使也’此案属心肾不交、阴虚火旺范畴。治宜滋阴降火、养心安神方剂思路可参考黄连阿胶汤或天王补心丹加减建议结合具体脉证由医师诊断后用药。”这个回答结构清晰先辨证、再引用原文、后给方剂方向信息分布符合训练时设计的输出格式。第二测试输入“《金匮要略》里对胸痹的论述是什么”模型输出为“《金匮要略·胸痹心痛短气病脉证治》记载‘胸痹之病喘息咳唾胸背痛短气寸口脉沉而迟关上小紧数。’胸痹的核心病机是阳微阴弦即上焦阳气不足阴寒之邪上乘导致胸背疼痛、短气。治法以通阳散结、豁痰下气为主瓜蒌薤白白酒汤为经典方。”这个回答直接引用了原文并且抓住了“阳微阴弦”这个病机关键说明模型通过训练学到了《金匮要略》的核心条文而不是简单的关键词匹配。4.3 训练中踩过的三个深坑第一个坑是灾难性遗忘。第一版训练完全使用中医古籍数据训练完成后发现模型的中文通用能力明显下降让它解释一个现代成语都变得吃力。解决方法是混入10%的通用中文指令数据保留原模型的对话基础效果好得多。第二个坑是过度文言化。模型学古籍学得太过投入回答任何问题都倾向于古文风格普通人根本看不懂。比如“风寒束表卫阳被遏”这种回答确认真实但患者看不懂。解决方法是把答案结构统一设计为“白话解释原文引用”并在instruction里明确要求现代白话优先。第三个坑是引用幻觉。模型在没有原文依据的情况下会编造出处。比如某个回答里写“《黄帝内经》有云”但《黄帝内经》里根本没这句话。这是生成式模型的通病不是微调能彻底解决的。我做了两层缓解训练数据里大量标记出处诱导模型更严谨地引用推理阶段在prompt里加约束明确要求“如果没有原文依据请说明不确定”。5. 模型仓库的使用从zip到可运行的问答系统5.1 压缩包里到底有什么这个项目以zip形式打包解开后的目录结构很有代表性代表了一个标准LoRA微调模型仓库应有的样子。核心内容包括文件/目录作用adapter_config.jsonLoRA配置记录目标模块、rank、alpha等参数adapter_model.safetensorsLoRA权重文件序列化格式tokenizer相关文件分词器配置必须与基座匹配README.md项目说明、数据来源、复现步骤data_sample.jsonl训练数据样例方便理解数据格式train_lora.sh训练脚本包含完整启动命令inference.py推理脚本加载模型并生成回答eval_sample.txt测试示例与预期输出这里要特别注意adapter_config.json和tokenizer文件。LoRA微调出来的不是完整模型只是一个适配器必须配合原模型的base weights才能运行。tokenizer文件也必须是Ziya-LLaMA配套的版本如果拿LLaMA原版tokenizer去加载Ziya微调后的adapter会直接报错或产生乱码。5.2 复现安装与推理部署复现的具体步骤按顺序走。先准备基础镜像这里用Python 3.10版本确保依赖兼容。安装依赖时transformers、peft、accelerate、bitsandbytes这几个库的版本要匹配我用的组合是transformers 4.30、peft 0.4.0、accelerate 0.21.0、bitsandbytes 0.39.0这套组合可以稳定跑通。加载模型的核心代码如下import torch from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig from peft import PeftModel model_name IDEA-CCNL/Ziya-LLaMA-13B-v1 adapter_path ./huangdi_adapter/ quant_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_compute_dtypetorch.float16, bnb_4bit_quant_typenf4, bnb_4bit_use_double_quantTrue, ) tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_name, quantization_configquant_config, device_mapauto, trust_remote_codeTrue, ) model PeftModel.from_pretrained(model, adapter_path) model.eval() def answer_from_guji(query, max_new_tokens512): prompt f你是研读中医古籍的智能助手。请基于古籍原文用现代白话回答{query} inputs tokenizer(prompt, return_tensorspt).to(cuda) outputs model.generate( **inputs, max_new_tokensmax_new_tokens, do_sampleTrue, temperature0.7, top_p0.9, ) return tokenizer.decode(outputs[0][len(inputs.input_ids[0]):], skip_special_tokensTrue)这个推理脚本兼顾了速度和效果。4bit量化加载让显存占用降到10GB以内16GB显存的卡就能流畅运行。temperature设置为0.7保留一定的生成多样性避免回答过于机械。5.3 部署方案的三个分支推理脚本可以跑通但距离“可用”还有距离。我实际部署时试过三种方案各有适用场景。第一种是单机交互脚本适合本地快速验证效果。把上面的inference.py封装成命令行工具一问一答改改prompt就能测试不同场景缺点是并发能力差。第二种是vLLM部署适合需要服务化调用的场景。先把LoRA权重与基座合并导出为一个完整的FP16或4bit模型再用vLLM的API服务器模式启动。这样能支持高并发请求还具备兼容OpenAI格式的接口方便集成到应用里。合并权重需要写几行代码但社区工具链已经很成熟transformers里调用merge_and_unload()方法即可完成。第三种是Ollama本地部署适合完全本地化的轻量使用。把模型转成GGUF格式配合Modelfile配置模板就可以通过Ollama的聊天界面使用。这种方案的推理速度和对私有化的友好度都很高缺点是转换步骤繁琐而且GGUF格式对LoRA的支持不如前两种方案直接。注意无论哪种部署方式医疗相关的问答系统都应设计免责声明。我在这套系统里加了一个内置提示当问题涉及具体用药和诊疗建议时模型会明确输出“以上内容仅供技术演示不构成医疗建议具体诊疗请就医”。这既是对用户的负责也是内容合规的基础底线。6. 复盘与扩展如何把这套流程复用到其他垂直领域6.1 这套方案能迁移到什么场景做完这个中医古籍项目最大的收获不是模型本身的性能而是一套可以复用的垂直领域微调方法论。它的适用场景有几个共同特征领域语料以特定风格文本为主、术语体系与日常生活差异大、回答需要依据来源、知识边界相对固定。我身边有人用同样的流程做法律条文问答——基座选中文能力强的13B模型数据采用法律条文和解释说明的问答对LoRA参数直接沿用效果很快就出来了。还有人做古籍诗词解析、地方方言和民俗文化问答、小众学科术语科普本质都是“让大模型学会一门特定语境下的语言”这套流程完全适配。迁移时需要注意两个差异点。第一个是数据规模。中医古籍标注充分的原文相对多但有些领域语料稀缺动辄只有几千字。这时可以先用通用大模型在盲标基础上生成候选样本再人工逐条审核修正保留高质量子集。第二个是模型遗忘倾向。法律、医疗这类对准确性要求高的领域混入的通用数据比例要适当增加防止模型在领域内“学得太深”反而丢掉基础安全能力。6.2 未来可以做的增强方向当前版模型只做了指令微调没有引入检索增强生成RAG。这是我认为最值得扩展的方向。做法是把《黄帝内经》《伤寒论》等古籍原文段落做向量化索引用户提问时先检索出相关原文片段拼接进prompt再交给模型生成回答。这样有两个直接收益答案的出处是真实检索得到的幻觉引用问题大幅降低用户能看到“依据了哪段原文”信任感会强很多。另一个方向是对话记忆。当前模型是单轮问答无法在连续对话中记住之前的症状信息。如果要支持真实的患者咨询场景需要加入多轮对话状态管理把历史对话压缩后一并输入模型。技术上不难做但对prompt设计和上下文长度管理有更高要求。还有一个我自己很感兴趣的方向对古籍版本进行对齐训练。不同版本的文字差异可以做成对齐样本让模型学会“同一条文在不同版本中的表述差异”这既能增强古文理解能力也能服务古籍数字化整理。有做数字人文方向的朋友尝试过类似思路效果超出预期。6.3 给后来者的一份经验清单把这次项目里踩过的坑和验证过的方法整理成一份清单供参考数据清洗花的时间应多于模型训练数据质量直接决定模型上限模型训练只是把数据里的信号学出来垂直领域数据要在通用数据里占合理比例常用参考值是九成领域数据加一成通用数据防止灾难性遗忘训练时保存多个checkpoint不要只保留最终权重过拟合时能回滚到中间状态不要迷信loss数值垂直领域效果评估靠人工质检比自动指标可靠医疗、法律等专业领域必须加免责声明模型输出永远不能替代专业意见基座模型、tokenizer、LoRA权重版本必须严格匹配混用会出各种莫名问题先用小实验验证数据格式和训练流程再上全量训练省时省力这套方法论在多个垂直领域通用核心就是两条认真准备数据谨慎设计prompt其他都是成熟工具链的工程问题。最后再分享一个小技巧训练集里每一条数据都可以加一行“拒绝回答”的样本对应那些超出古籍范围的问题比如现代医学影像解读、手术方案选择。模型见过这类样本后面对不懂的问题会倾向于说“古籍中没有记载”而不是强行生成答案。这个细节能显著提升输出的可信度也是技术演示转为实际应用时很重要的一步。本文还有配套的精品资源点击获取
返回列表