恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

DeepSeek模型高效微调与部署全流程实战指南

  • 首页
  • 资讯中心
  • /
  • DeepSeek模型高效微调与部署全流程实战指南

相关资讯

YOLOv13改进策略【Head篇】| YOLOv6 官方 EfficientDecoder 解耦头,SE 尺度先验加硬件友好通道 2026/9/30 2:45:30
给景区装上“AI 大脑”:一张图看懂景区,一句话排好行程 2026/9/30 2:40:30
基于STM32单片机激光测距仪TOF激光传感器VL53L1X倒车雷达蓝牙/WiFi/视频监控/云平台无线APP-DIY设计S450 2026/9/30 2:40:30

最新资讯

WiFi-DensePose:当路由器成为隐形雷达,解锁无线人体姿态感知
MySQL密码加密存储与查询实战:从bcrypt选型到JDBC集成
开题答辩实战:校园扶助综合服务平台设计与实现全流程解析
2026自助建站系统怎么选?四大流派与避坑指南
MySQL视图、存储过程与触发器实战:从权限坑到性能陷阱
无标题项目不是问题:不急着起名也能高效推进

今日推荐

模型优化器实战:从FP32到INT8的推理加速与精度平衡
LangGraph+FastAPI构建可审计AI编码助手
基于图像预处理与几何特征的人脸脸型发型搭配系统实现

本周热门

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

DeepSeek模型高效微调与部署全流程实战指南

发布时间:2026/9/30 2:45:31
DeepSeek模型高效微调与部署全流程实战指南 简介本资源是一份面向大模型工程师与AI算法研究员的DeepSeek专项技术手册系统覆盖高效训练、轻量化适配与工业级部署全链路优化方案。聚焦LoRA微调调优、量化感知训练、知识蒸馏、模型压缩及推理部署等核心瓶颈问题特别适配DeepSeek系列模型在算力受限场景下的落地实践。文档共236页含50个深度章节PDF格式单文件10.77MB支持目录跳转与左侧书签大纲导航文字图表完整清晰便于逐模块精读与工程复用。内容从DeepSeek架构剖析、分布式训练环境搭建、数据预处理规范到LoRA秩选择策略、量化校准方法、过拟合抑制技巧及LoRA-原生层融合方案等均有详实推演与实操建议前20章已涵盖注意力机制优化、梯度检查点显存管理、混合精度训练适配等关键细节。目前已有427人学习下载是兼顾理论深度与工程颗粒度的高质量技术参考材料。1. DeepSeek高效训练与性能优化全流程详解这不是一份“理论手册”而是我用236页PDF踩出来的部署流水线你手头刚拉下来一个deepseek-llm-7b-base想在单卡3090上跑通LoRA微调结果CUDA out of memory报错三次、量化后推理速度不升反降、蒸馏出来的模型在业务query上掉点5个点——这根本不是模型不行是你没把DeepSeek的训练-压缩-部署链条拧紧。这份《DeepSeek高效训练与性能优化全流程详解》236页PDF不是泛泛而谈的“原理综述”它是一份按真实产线节奏拆解的可执行技术流水线从LoRA适配器的rank与alpha如何配比才能兼顾收敛速度与显存占用到Qwen-style tokenizer在DeepSeek-v2/v3上的token对齐陷阱从GGUF量化时--quant_type q4_k_m和--quant_type q5_k_m在长文本生成中的困惑度差异到vLLM部署时--enforce_eager必须开还是必须关的血泪判断。它面向两类人一是刚跑通HuggingFaceTrainer但卡在peft参数调优的算法工程师二是已拿到.safetensors却不敢上线、反复重训的MLOps同学。全文不讲Transformer架构只讲“哪一行代码改了会让batch_size从8变成16”、“哪个量化参数设错会导致JSON Schema解析失败”。2. LoRA适配器调优从参数配置到收敛监控的闭环实践LoRA不是“加个peft_config就完事”的黑盒。DeepSeek系列尤其v2/v3的attention层结构与Qwen、Llama存在细微差异——其q_proj/k_proj/v_proj/o_proj权重矩阵形状、RoPE embedding偏移量、以及flash attention kernel的padding策略都会直接影响LoRA rank的敏感度。盲目套用r8, alpha16在DeepSeek上大概率导致梯度爆炸或收敛停滞。本章基于236页PDF中第47–89页的实测数据给出可复现的调优路径。2.1 Base Model与LoRA配置的硬约束校验DeepSeek官方发布的deepseek-llm-7b-baseHF hub ID:deepseek-ai/deepseek-llm-7b-base要求tokenizer必须使用deepseek-ai/deepseek-llm-7b-base配套的tokenizer.json而非通用LlamaTokenizer。若强行加载QwenTokenizer会在prepare_inputs_for_generation阶段因|endoftext|token id不匹配引发IndexError。验证方式如下from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained(deepseek-ai/deepseek-llm-7b-base) print(fbos_token_id: {tokenizer.bos_token_id}) # 应为 100000 print(feos_token_id: {tokenizer.eos_token_id}) # 应为 100001 print(fpad_token_id: {tokenizer.pad_token_id}) # 应为 100002 print(fvocab_size: {len(tokenizer)}) # 应为 100004提示若输出bos_token_id1或vocab_size128256说明加载了错误tokenizer需清空缓存并重试。LoRA配置必须与base model的config.json中num_attention_heads、hidden_size严格对齐。DeepSeek-7B的hidden_size4096num_attention_heads32因此rrank建议取值范围为4~16lora_alpha应为r的整数倍常见alpha2*r。lora_dropout在DeepSeek上不宜设为0会加剧过拟合实测0.05~0.1为安全区间。2.2 训练脚本最小化启动与关键参数注入以下为236页PDF中第53页提供的最小可运行LoRA训练脚本基于peft0.11.1transformers4.38.2# train_lora.py from peft import LoraConfig, get_peft_model from transformers import AutoModelForCausalLM, TrainingArguments, Trainer import torch base_model deepseek-ai/deepseek-llm-7b-base train_data ./data/train.jsonl # 格式: {text: 用户输入\n助手回答} val_data ./data/val.jsonl output_dir ./lora_output # LoRA配置针对DeepSeek-7B的实测最优组合 peft_config LoraConfig( r8, lora_alpha16, target_modules[q_proj, k_proj, v_proj, o_proj], # 必须显式指定DeepSeek不支持all-linear lora_dropout0.05, biasnone, task_typeCAUSAL_LM ) model AutoModelForCausalLM.from_pretrained( base_model, torch_dtypetorch.bfloat16, device_mapauto, trust_remote_codeTrue ) model get_peft_model(model, peft_config) model.print_trainable_parameters() # 输出: trainable params: 3,932,160 || all params: 6,738,192,384 || trainable%: 0.0584 # 数据集加载使用streaming避免OOM from datasets import load_dataset train_ds load_dataset(json, data_filestrain_data, splittrain) val_ds load_dataset(json, data_filesval_data, splittrain) def tokenize_function(examples): return tokenizer( examples[text], truncationTrue, max_length2048, paddingmax_length, return_tensorspt ) train_tokenized train_ds.map(tokenize_function, batchedTrue, remove_columns[text]) val_tokenized val_ds.map(tokenize_function, batchedTrue, remove_columns[text]) training_args TrainingArguments( output_diroutput_dir, per_device_train_batch_size4, # 单卡3090实测最大值 per_device_eval_batch_size4, gradient_accumulation_steps8, # 等效batch_size32 num_train_epochs3, learning_rate2e-4, warmup_ratio0.03, logging_steps10, save_steps200, eval_steps200, evaluation_strategysteps, fp16False, # DeepSeek-v2/v3必须用bfloat16 bf16True, report_tonone, optimadamw_torch_fused, # 显著加速但需PyTorch2.2 max_grad_norm0.3, load_best_model_at_endTrue, metric_for_best_modeleval_loss, greater_is_betterFalse ) trainer Trainer( modelmodel, argstraining_args, train_datasettrain_tokenized, eval_datasetval_tokenized, tokenizertokenizer ) trainer.train()关键参数说明per_device_train_batch_size4DeepSeek-7B在309024GB上实测极限若设为8会触发CUDA out of memorygradient_accumulation_steps8通过梯度累积模拟大batch避免显存超限bf16TrueDeepSeek官方明确要求bfloat16fp16会导致NaN lossoptimadamw_torch_fused比默认adamw_hf快18%但需确认PyTorch版本≥2.2max_grad_norm0.3DeepSeek梯度方差较大设为1.0易导致loss震荡。2.3 LoRA训练过程中的收敛监控与早停策略仅靠eval_loss判断收敛极易误判。DeepSeek在长文本任务如SQL生成、多跳推理中loss下降但BLEU-4不升是典型现象。236页PDF第68页提出三维度监控法指标计算方式健康阈值触发动作Token-level accuracycorrect_tokens / total_tokens仅计算endoftext前tokenFirst-token correctness首个生成token是否为ground truth首token 95%若连续下跌检查prompt模板Loss variance (last 10 steps)std(loss_list[-10:]) 0.0050.015则启用early_stopping_patience2实现该监控需重写Trainer.compute_loss并注入自定义callbackclass DeepSeekLoRACallback(TrainerCallback): def __init__(self, tokenizer): self.tokenizer tokenizer self.loss_history [] self.acc_history [] def on_log(self, args, state, control, logsNone, **kwargs): if loss in logs: self.loss_history.append(logs[loss]) if len(self.loss_history) 10: self.loss_history.pop(0) if eval_loss in logs: # 计算token-level accuracy preds kwargs[model].generate( input_idskwargs[eval_dataloader].dataset[0][input_ids][:1].to(cuda), max_new_tokens64, do_sampleFalse ) labels kwargs[eval_dataloader].dataset[0][labels][:1] acc (preds[:, :labels.shape[1]] labels).float().mean().item() self.acc_history.append(acc) logs[token_acc] acc def on_step_end(self, args, state, control, **kwargs): if len(self.loss_history) 10: var torch.tensor(self.loss_history).std().item() if var 0.015: control.should_training_stop True print(f[Early Stop] Loss variance {var:.4f} 0.015)将此callback传入Trainer(callbacks[DeepSeekLoRACallback(tokenizer)])即可生效。3. 量化蒸馏用知识蒸馏压缩DeepSeek模型的实操边界量化Quantization与蒸馏Distillation常被混为一谈但在DeepSeek场景下二者是互补而非替代关系量化解决部署时显存与延迟问题蒸馏解决小模型能力天花板问题。236页PDF第112–156页明确指出直接对deepseek-llm-7b做INT4量化其长文本生成质量尤其是JSON Schema输出稳定性会断崖式下跌而先用deepseek-llm-7b作为teacher蒸馏出deepseek-llm-1.3b再对1.3B做INT4量化才是工业级可行路径。本章聚焦蒸馏环节——不是“怎么跑通DistilBERT”而是“如何让DeepSeek teacher的logits不泄露未来信息”。3.1 蒸馏数据构造避免“未来信息泄露”的三原则知识蒸馏的核心是teacher模型的soft logits指导student训练。但DeepSeek的因果语言建模CLM特性导致一个致命陷阱若蒸馏数据直接用teacher对原始prompt的完整生成结果如prompt answerstudent在训练时会看到answer中后续token对前面token的依赖即“未来信息泄露”future information leakage。236页PDF第121页给出三原则Mask future tokensteacher只输出prompt对应位置的logits不生成answerUse causal masking strictlystudent的attention mask必须与teacher完全一致Align tokenization byte-levelDeepSeek tokenizer的byte-fallback机制易导致teacher/student分词不一致必须强制add_special_tokensFalse。具体实现# distill_data.py from transformers import AutoTokenizer, AutoModelForCausalLM import torch teacher AutoModelForCausalLM.from_pretrained( deepseek-ai/deepseek-llm-7b-base, torch_dtypetorch.bfloat16, device_mapauto ) tokenizer AutoTokenizer.from_pretrained( deepseek-ai/deepseek-llm-7b-base, add_special_tokensFalse # 关键避免|endoftext|插入导致长度错位 ) def build_distill_sample(prompt: str, max_len2048): inputs tokenizer( prompt, return_tensorspt, truncationTrue, max_lengthmax_len - 1, # 为label留1位 paddingmax_length ) # teacher只计算prompt部分的logits不生成 with torch.no_grad(): outputs teacher( input_idsinputs[input_ids].to(cuda), attention_maskinputs[attention_mask].to(cuda) ) teacher_logits outputs.logits # shape: [1, seq_len, vocab_size] # label prompt右移1位标准CLM但teacher_logits对应原始position labels inputs[input_ids].clone() labels[labels tokenizer.pad_token_id] -100 # ignore pad return { input_ids: inputs[input_ids][0], attention_mask: inputs[attention_mask][0], labels: labels[0], teacher_logits: teacher_logits[0, :-1, :] # 去掉最后1位logit与label对齐 } # 构造1000条蒸馏样本 distill_samples [] for line in open(./data/distill_prompts.txt): prompt line.strip() if len(prompt) 10: distill_samples.append(build_distill_sample(prompt))注意teacher_logits[0, :-1, :]是关键——teacher输出logits长度为seq_len但label是input_ids右移故teacher logits需截去最后一位否则shape不匹配。3.2 蒸馏损失函数KL散度Hard Label双目标单纯KL散度蒸馏会导致student生成多样性下降。236页PDF第135页推荐混合损失$$ \mathcal{L} \lambda_{kl} \cdot KL(\text{student_logits} \parallel \text{teacher_logits}) (1-\lambda_{kl}) \cdot CE(\text{student_logits}, \text{hard_labels}) $$其中hard_labels为原始token idCE为交叉熵。lambda_kl设为0.7时在DeepSeek-1.3B蒸馏中BLEU-4提升2.3点同时保持生成多样性。def distill_loss(student_logits, teacher_logits, labels, lambda_kl0.7): # student_logits: [seq_len, vocab_size], teacher_logits: [seq_len, vocab_size] # labels: [seq_len], -100 for pad # KL loss (ignore pad positions) valid_mask (labels ! -100) kl_loss F.kl_div( F.log_softmax(student_logits[valid_mask], dim-1), F.softmax(teacher_logits[valid_mask], dim-1), reductionbatchmean ) # CE loss ce_loss F.cross_entropy( student_logits[valid_mask], labels[valid_mask], reductionmean ) return lambda_kl * kl_loss (1 - lambda_kl) * ce_loss3.3 Student模型初始化避免“蒸馏冷启动失败”直接用torch.nn.init.xavier_normal_初始化student会导致蒸馏初期KL loss爆炸。236页PDF第142页实测发现对student的embedding层和final lm_head应采用teacher对应层的SVD分解权重初始化# 初始化student embedding teacher_emb teacher.get_input_embeddings().weight.data # [vocab_size, hidden_size] U, S, Vh torch.svd(teacher_emb.float()) # float for stability student_emb U[:, :student_hidden_size] torch.diag(S[:student_hidden_size]) Vh[:student_hidden_size, :] student.model.embed_tokens.weight.data.copy_(student_emb.half())同理对lm_head做相同操作。此举使student初始logits与teacher相似度提升3.7倍蒸馏收敛步数减少40%。4. 模型压缩与部署从GGUF量化到vLLM服务化的全链路避坑拿到LoRA微调后的adapter_config.json和adapter_model.bin或蒸馏量化后的.gguf文件下一步是上线。但“部署”不是llama.cpp -m model.gguf -p Hello就能完事——DeepSeek的特殊token、长上下文处理、JSON Schema强约束会让看似成功的本地推理在线上API中集体翻车。本章基于236页PDF第178–225页的线上故障日志梳理出6类高频问题及根因。4.1 GGUF量化参数选择q4_k_m vs q5_k_m的实测分水岭DeepSeek官方未发布GGUF格式模型社区常用llama.cpp工具链转换。但不同量化类型对DeepSeek的RoPE插值、attention softmax精度影响巨大Quant TypeSize (GB)PPL (WikiText)JSON Schema CorrectnessLong Context (8K) Stabilityq4_k_m3.88.2163.4%❌ frequent OOM at 8192q5_k_m4.77.0389.1%✅ stable up to 12288q6_k5.96.4292.7%✅ but 30% slower than q5_k_m结论生产环境首选q5_k_m。q4_k_m虽小但DeepSeek的rope_theta1000000导致低比特量化时位置编码失真引发长文本生成重复或截断。量化命令必须指定--rope-freq-base 1000000python llama.cpp/convert-hf-to-gguf.py \ --outtype f16 \ --outfile deepseek-7b-f16.gguf \ deepseek-ai/deepseek-llm-7b-base ./llama.cpp/llama-quantize \ deepseek-7b-f16.gguf \ deepseek-7b-q5_k_m.gguf \ q5_k_m \ --rope-freq-base 1000000 # 关键否则RoPE失效4.2 vLLM部署时的DeepSeek专属配置vLLM 0.4.2 支持DeepSeek但需手动注入DeepseekV2Attentionpatch。否则会出现KeyError: q_lora_rank或attention结果错乱。# vllm_patch.py from vllm.model_executor.models.deepseek_v2 import DeepseekV2ForCausalLM from vllm.model_executor.layers.attention import Attention # 替换原attention为DeepSeek兼容版 original_init Attention.__init__ def patched_init(self, *args, **kwargs): if q_lora_rank in kwargs: kwargs.pop(q_lora_rank, None) original_init(self, *args, **kwargs) Attention.__init__ patched_init # 启动vLLM时指定 # python -m vllm.entrypoints.api_server \ # --model ./deepseek-7b-q5_k_m.gguf \ # --dtype bfloat16 \ # --tensor-parallel-size 1 \ # --enable-prefix-caching \ # --max-model-len 12288 \ # --enforce-eager # 必须开启否则flash-attn与DeepSeek RoPE冲突提示--enforce-eager禁用CUDA graph牺牲5%吞吐但避免RoPE计算错误——这是DeepSeek v2/v3的已知限制。4.3 JSON Schema生成的稳定性加固DeepSeek在生成JSON时易出现{key: value,}末尾逗号或{key: value缺右括号。236页PDF第215页给出两种加固方案Grammar-constrained decoding推荐使用outlines库定义JSON schema强制生成语法正确结构from outlines import models, generate import json model models.llamacpp(./deepseek-7b-q5_k_m.gguf, n_gpu_layers1) schema {type: object, properties: {name: {type: string}, age: {type: integer}}} generator generate.json(model, schema) result generator(Extract user info:) # result guaranteed to be valid JSON dictPost-hoc repair备选对生成结果做正则修复import re def repair_json(s): s re.sub(r,\s*}, }, s) # 删除末尾逗号 s re.sub(r\{([^}]*)$, r{\1}, s) # 补右括号 s re.sub(r([^]*):, r\1:, s) # 修复key缺冒号 return s5. 常见问题排查DeepSeek训练与部署的5个血泪坑注意以下问题均来自236页PDF附录“线上事故复盘表”非理论推测每一条都对应至少3次线上P0故障。5.1 现象LoRA微调后model.generate()输出全为|endoftext|原因LoRA adapter未正确注入到o_proj层或target_modules漏写o_proj。DeepSeek的o_proj负责attention输出投影若未适配logits全为零。解决检查peft_config.target_modules必须包含[q_proj,k_proj,v_proj,o_proj]且get_peft_model后调用model.print_trainable_parameters()确认o_proj权重显示为trainable。5.2 现象GGUF量化后llama.cpp推理速度比FP16还慢原因未启用--no-mmap和--no-mlock。DeepSeek的KV cache在量化后内存布局更紧凑mmap会引发频繁page fault。解决启动命令加--no-mmap --no-mlock实测提速2.1倍./llama.cpp/main -m deepseek-7b-q5_k_m.gguf -p Hello --no-mmap --no-mlock5.3 现象vLLM服务返回{error:CUDA error: an illegal memory access was encountered}原因--max-model-len设置超过模型实际支持长度。DeepSeek-7B官方支持最长8192但vLLM默认设为32768超出部分触发GPU越界访问。解决严格按模型config设置--max-model-lenDeepSeek-7B用--max-model-len 8192DeepSeek-67B用--max-model-len 12288。5.4 现象蒸馏后student模型在测试集上BLEU-4高但线上query准确率暴跌原因蒸馏数据未覆盖线上真实分布。PDF第152页统计显示线上73% query含嵌套JSON或SQL而蒸馏数据92%为纯文本问答。解决构建domain-specific distillation corpus——用线上bad case query teacher生成答案而非通用语料。5.5 现象LoRA微调loss下降但eval时token_acc始终10%原因tokenizer的padding_sideleft未设。DeepSeek要求左填充left-pad以保证attention mask正确否则|endoftext|位置错乱。解决初始化tokenizer后立即执行tokenizer.padding_side left tokenizer.pad_token tokenizer.eos_token # 必须设否则pad_id为None6. 进阶技巧用DeepSeek Harness做端到端流水线编排与灰度验证236页PDF第226–236页提出的DeepSeek Harness不是新框架而是一套标准化CLI工具链将LoRA训练、蒸馏、量化、部署打包成可审计、可回滚的流水线。它解决了“改一行代码就要重跑整个流程”的工程痛点。核心思想每个环节输出带哈希签名的制品artifact下游环节只认签名不认路径。6.1 Harness流水线定义YAML驱动的原子任务pipeline.yaml示例version: 1.0 stages: - name: lora_train image: deepseek-harness:0.3.1 command: [train, --config, lora_config.yaml] inputs: - base_model: deepseek-ai/deepseek-llm-7b-base - train_data: s3://bucket/data/train.jsonl outputs: - adapter: ./output/adapter/ - metrics: ./output/metrics.json - name: distill image: deepseek-harness:0.3.1 command: [distill, --teacher, stage:lora_train:adapter, --student, deepseek-llm-1.3b] inputs: - distill_data: s3://bucket/data/distill_prompts.txt outputs: - student_model: ./output/student/ - name: quantize image: deepseek-harness:0.3.1 command: [quantize, --model, stage:distill:student_model, --type, q5_k_m] outputs: - gguf_model: ./output/model.q5_k_m.gguf - name: deploy image: deepseek-harness:0.3.1 command: [deploy, --model, stage:quantize:gguf_model, --vllm-config, vllm.yaml]执行命令deepseek-harness run pipeline.yaml --stage deploy --dry-run # 先预检输出将要部署的gguf hash、vLLM版本、GPU型号 deepseek-harness run pipeline.yaml --stage deploy --canary 5% # 灰度5%流量自动对比新旧模型latency accuracy6.2 灰度验证的三个必监指标Harness内置对比逻辑不依赖人工看板。每次灰度自动计算指标计算方式阈值动作Latency deltap95(new) - p95(old) 150ms暂停灰度检查quantization typeToken accuracy deltaacc(new) - acc(old) -0.5%回滚检查蒸馏数据分布OOM rateOOM_count / total_requests 0.1%检查--max-model-len与--gpu-memory-utilization6.3 我的Harness使用习惯永远保留3个历史制品DeepSeek模型迭代快v2→v3→v4半年一更。我强制自己每次harness run后deepseek-harness export --stage quantize --tag v3.2.1导出制品所有制品存S3路径为s3://models/deepseek/{model}/{version}/CI/CD中deploy阶段必须指定--require-tag v3.2.1禁止用latest每月清理v3.*旧版但v3.2.1、v3.2.2、v3.2.3永久保留——因为某次线上bug只能靠v3.2.2回滚。这套机制让我在过去14个月里0次因模型更新导致线上服务中断。不是因为技术多高超而是把“可追溯、可回滚、可验证”刻进了流水线DNA里。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号