真正让我下决心做“万象灵码”这个项目,是在一次汽车焊装车间的调研里。生产线的PLC工程师想统计每把焊枪每天的有效焊接次数,需求本身很简单,但如果把活儿交给通用编码大模型,它会反问你:什么是焊枪?什么是工位节拍?即使你强行让它生成嵌入式代码,它也大概率会把“读取输入寄存器”写成一个HTTP请求。当时我们团队已经在给工厂做数据中台,测试了不少主流的编码大模型,结论很一致:面向智能制造的编码大模型,缺的不是参数规模,而是真正懂车间语言的数据、微调方式和部署方案。于是我们启动了“万象灵码”这个项目,定位是围绕PLC、SCADA、工业机器人等现场程序生成场景,做一套从数据到微调到私有化部署的完整工程体系。
如果你也在做工业AI平台、企业私有化大模型,或者正打算给组态软件、MES、低代码平台内嵌AI助手,这篇文章应该能给你一些可以直接抄走的经验。我不打算讲抽象概念,而是把我们在车间里踩过的坑、测过的数据、改过的训练策略,尽量摊开来讲。
1. 通用编码大模型在产线面前失灵,问题不在模型而在“语言环境”
1.1 工业编程不是写Java/Python,而是和设备对话
做工业软件的朋友都知道,智能制造现场真正的“代码”和互联网开发完全是两个物种。PLC程序遵循IEC 61131-3标准,常见形态有梯形图、结构化文本、功能块图;数控机床用G代码和M代码;工业机器人各自有专用语言,比如库卡的KRL、发那科的TP程序、ABB的RAPID;再往上还有SCADA组态脚本、MES里的配方引擎配置和历史数据库SQL。这些程序的特点是:不追求架构优美,只追求在一定约束下稳定、安全地控制物理设备。动辄几千行的梯形图转成文本后,信息密度一点不比普通项目低。
更要命的是,这类程序几乎不会进开源社区。一个PLC项目文件通常绑定具体的设备型号、PLC标签表、总线从站配置和工艺参数,即使有人把代码传到GitHub,也往往因为脱敏不完整、格式特殊而被当成噪音清理掉。所以通用编码大模型的训练语料里,工业控制代码的占比低到可以忽略。它不是不会写,而是根本没学过。
1.2 通用模型在工业场景下的三大断裂
我们做了大量测试后,把失败原因归纳成三组:语料断裂、上下文断裂、安全断裂。
语料断裂很好理解:通用代码大模型的代码库以Java、Python、JavaScript、C/C++为主,SQL和Shell也不少,但IEC 61131-3的结构化文本、CNC的宏程序、机器人的示教文件,它只在极偶然的样本里扫到过。你让它生成一段“启动电机前先检查热继电器状态”的ST代码,它可能给你生成一段Python伪代码。
上下文断裂更隐蔽:工业代码的正确性高度依赖上下文。同样是“读取变量”,在西门子S7-1500里读的是DB块绝对地址,在CODESYS里读的是符合IEC 61131-3的命名变量,在OPC UA里则是带命名空间的节点路径。通用模型不知道你用的是哪个品牌、哪一版固件、哪个工位。它生成的代码看着合理,放到实际控制器里却连变量名都解析不了。
安全断裂是最不能被接受的:通用模型会非常自信地生成一段“看起来合法但运行起来会出事故”的代码。比如让机器人从A点移动到B点,它可能漏掉速度限制、漏掉到位等待信号,甚至漏掉安全门互锁。普通软件代码的bug是返工,工业代码的bug是撞机、损坏设备。所以我们对生成内容的评判标准,天然比互联网代码严格一个量级。
2. 万象灵码的技术内核:先把“车间语言”变成模型的母语
2.1 底座选型:7B级开源模型是私有化部署的性价比拐点
明确了痛点之后,第一个决定是选底座。制造企业对数据外发有硬性要求,现场程序、工艺配方、设备型号都不能传到外部API,所以“私有化部署”是底线,不是加分项。这直接排除了需要大规模算力的巨型模型,也排除了纯云端方案。
实测下来,7B这个体量是最合适的切入点:一张RTX 4090或A800就能做推理,如果上双卡,配合量化甚至能跑不错的并发;训练层面,7B也能在单机多卡上完成QLoRA微调,迭代速度快。相比之下,70B级别的底座在效果上有优势,但部署成本和推理延迟对产线项目来说过于沉重,客户很难为一个代码助手专门配一个8卡集群。我们的选择是先用Qwen2.5-7B这类开源底座做基础,把数据、评测、工程链路跑通,再根据场景需要评估是否升级到14B档位。
2.2 数据管线:设备手册、历史程序和工艺配方如何变成训练语料
底座只是起点,万象灵码真正的护城河在数据。我们当时动员了电气工程师、自动化集成商技术员和工厂IT三拨人,从现场扒出来几类宝贵语料:
- 甲方遗留的PLC工程导出文件,包括主流平台的程序源码和变量表;
- 设备手册中的功能块说明、报警代码表、工艺参数范围;
- MES/SCADA里的历史脚本、报表模板、配方配置;
- 老师傅和电气工程师的日常问答记录,包括故障处理、程序优化、启停操作。
这些数据不能直接用,至少要过四道清洗工序。第一道是脱敏,去掉厂商项目名、客户标识、人员姓名、IP地址,这些信息一旦进入训练集,轻则合规风险,重则泄露工艺机密。第二道是格式归一化,我们把梯形图、功能块图统一转成结构化文本,G代码统一大小写和注释风格,保证模型学到的不是格式噪音。第三道是设备实体对齐,把同一品牌不同叫法归一成统一实体,顺便建立品牌和指令集的映射关系。第四道是负样本标注,把“会绕过互锁”“漏掉到位检测”“缺少急停处理”的程序片段单独挑出来,标注成安全负样本,这部分在后面训练时发挥的作用极大。
2.3 从“文本生成”到“工程对象生成”
纯文本视角处理工业代码会撞到一堵墙:模型即使学会了语法,也理解不了语义。这里我们做了一个关键设计——在数据层建立“工程对象视图”,把程序看成对设备对象、变量、工艺步骤的操作序列,而不是一串字符。
具体做法是:从PLC变量表里抽取工位号、设备名、传感器类型、执行器类型,从设备手册里抽取动作规则,构造出“工位描述-变量引用-动作序列”对齐的数据。训练时,模型学习的就不是“这段代码长什么样”,而是“用户说传送带启动前要检查光电传感器,应该先读哪个变量,再置位哪个输出”。这个转变非常重要,它让模型在遇到没见过的设备名时,至少能按照“先读状态、再判断、后输出”的工业逻辑来推理,而不是毫无意识地续写代码。
3. 真正动模型之前,我们先把数据配比、微调策略和评测闭环想清楚了
3.1 数据配比:一句话决定模型偏科方向
训练数据不是多多益善,配比错了,模型会偏科。我们经过三轮实验,最终把通用代码、工业指令代码、设备手册问答、安全负样本的比例定在30:45:15:10。
通用代码占三成,是为了防止灾难性遗忘,保住模型的基础编程能力;工业指令代码占最多,是核心能力来源,包括“给需求生成ST代码”“根据梯形图转成文本”“把G代码加注释”等任务;设备手册问答占15%,让模型学会回答“这个报警代码是什么意思”“这个功能块的输入输出怎么接”这类问题,这对生成代码时的上下文理解帮助很大;安全负样本虽然只占10%,却直接决定了模型会不会生产高危代码。如果负样本比例太低,模型只知道“安全代码长什么样”,不知道“不安全代码有多危险”;比例太高,模型又会变得过于保守,经常输出“这段操作需要人工确认”而不干活。
3.2 微调方式:QLoRA为主,关键模块全参精调
微调方式我们做了三个方案对比:全参微调、LoRA、QLoRA。全参微调效果理论上最好,但7B模型全参跑一轮需要两张以上4090连续多天,迭代太慢;LoRA相对轻量,但秩的选择很敏感;QLoRA把底座量化到4bit再挂LoRA,单卡就能跑,初期验证数据方向非常合适。
我们的实际流程是:第一轮用QLoRA快速跑数据配比实验,r取64、alpha取128、学习率2e-4,训练3个epoch,序列长度根据工业程序长度设到4096;数据方向验证通后,再针对代码生成模块的核心层做全参精调,修正QLoRA在极端语法上的不足。这里有个坑:工业程序经常同时包含中文注释、设备英文名和结构化文本语法,预训练分词器对中文和ST混排的代码效果一般,我们在领域继续预训练阶段扩充了词表,专门加入厂商设备和指令相关token。
3.3 三阶段训练:继续预训练、指令微调、偏好对齐
真正训练是分三个阶段推进的。阶段一叫领域继续预训练,输入是清洗后的PLC程序文本和设备手册,让模型先“认识”这个领域的语言形态,包括ST的语法结构、G代码的格式规则、常见设备型号的拼写方式。阶段二是指令微调,我们把需求描述、设备上下文、期望输出整理成指令对,要求模型生成带注释、可编译的程序。阶段三是偏好对齐,我们用人工评审的方式对模型生成的多个答案排序,安全性和可维护性优先,然后用DPO把“会绕过互锁”这类答案压下去。三个阶段缺一个,模型在真实场景就会暴露出明显短板:只有预训练,它只会续写不会听指令;只有指令微调,它对危险代码的辨别力不足;只做完前两个不做对齐,生成的代码经常缺注释、缺异常处理。
3.4 评测体系:能编译、能仿真、能跑才能算过
评测是这套体系里最容易被低估的部分。我们坚决不用BLEU和ROUGE这种文本相似度指标来验收生成结果,因为工业代码的相似度和正确性没有强相关。我们的评测分三层:语法层直接丢进厂商编译器或语法解析器,检查能不能通过;语义层把程序放进PLC模拟器或机器人仿真环境,看运行结果是否符合需求;安全层用规则引擎检查互锁、回零、限位、急停逻辑有没有被绕过。每调整一次数据配比或训练参数,都要把三层回归集完整跑一遍,这个回归集里有真实产线程序、有我们构造的危险样本,还有一批专门测注释覆盖率的中文注释程序。
4. 部署与落地:编码大模型要跑在车间里,而不是PPT里
4.1 私有化一体机与vLLM推理
模型再好,部署方案不接地气,客户也不买账。我们把万象灵码的默认交付形态做成“一体机+私有化软件栈”:一台双卡GPU服务器,预装推理引擎、数据管道、评测工具和Web管理台。推理引擎用vLLM,模型做AWQ 4bit量化,实测在双卡配置下能稳定支撑20到30路并发请求,首Token延迟300到500毫秒,后续Token吞吐每路每秒35到50个Token。对于代码生成这种交互式任务来说,这个体验已经接近商用Web应用。
有人问为什么不直接用云厂商的托管服务,统一升级也方便。答案是工业客户对“数据不出厂”几乎是刚需,PLC程序、设备变量表是企业的核心工艺资产,任何一个懂行的甲方都不会同意把它们放到第三方服务器上。私有化部署多出来的运维成本,可以由一体机的远程运维通道来分摊,模型更新走增量包推送,不需要现场人员动命令行。
4.2 与工业软件的三种集成方式
光有模型服务不行,还得让工程师手边的工具能用起来。我们做了三种集成方式,覆盖不同场景。
第一种是IDE/组态软件插件,在CODESYS、TIA Portal、组态王这类软件里做侧边栏,工程师选中一段梯形图或变量表,插件自动生成注释、补全程序或翻译成结构化文本。第二种是API网关,把模型能力封装成REST接口,供MES、低代码平台、报表系统调用,输入需求文本返回代码和说明文档,适合做一个“智能工单助手”之类的应用。第三种是边缘Agent,在工控机旁部署轻量量化模型,支持离线生成,网络断开时也能应急写一段临时脚本。三条线都不是简单套壳:插件层要处理IDE的版本兼容,API层要设计好上下文管理,边缘Agent要省显存,每个方向都各自有坑。
4.3 安全护栏:规则引擎和外层校验
有段时间我们很激进,直接让模型生成PLC程序并自动下发到仿真控制器,结果在一台仿真的倍福控制器上差点复现撞机,之后我们彻底收敛了流程。现在所有生成结果要过三道护栏:第一道是语法合法性检查,用厂商编译器做静态校验;第二道是危险模式过滤,规则引擎里维护着一个高危Pattern库,包括“删除急停逻辑”“无限制跳转”“绕过安全门互锁”“修改回零条件”等类别,命中直接拦截;第三道是人工确认和仿真运行,AI生成的代码只能作为建议,必须由持证工程师确认后才允许部署。这套护栏同时也是一个反馈采集器,工程师每次修改AI代码的diff都会回流到数据集,形成“生成-纠正-再训练”的闭环。
5. 实测复盘:从“注释生成”到“焊接工位脚本”的完整链路
5.1 需求描述与输入
这里分享一个我们做过的真实案例:某汽车焊装车间需要给SCADA系统增加一个统计功能,读取焊枪控制器的焊接计数和报警状态,每天生成一张CSV报表。原来的做法是IT工程师从零手写,要花40到50分钟,而且这类需求经常被排期延后。我们用万象灵码的API侧接口,直接在MES工单系统里输入自然语言需求:
“请生成一个Python脚本,连接OPC UA服务器,读取焊枪控制器节点ns=2;s=Weld_Count和ns=2;s=Alarm_Code,统计每日焊接次数和报警次数,按天生成CSV报表,脚本要包含日志、异常重试和超时处理。”
5.2 模型生成结果与人工修正
模型在第一次尝试就生成了一个结构很完整的脚本:导入逻辑、日志配置、OPC UA连接、按天统计、CSV写出、异常重试,注释也很到位,基本能达到可以进code review的水平。人工修正了两处:第一处是OPC UA节点路径被写死,实际现场节点的命名空间是动态变化的,需要从配置文件中读取;第二处是时区处理少了一环,报表日期默认用了服务器本地时区,而现场要求按车间所在地时区统计。这两处都是业务上下文问题,不是语法问题,人工修改花了大约5分钟。
5.3 量化数据
我们把这次生成的过程跑了完整记录,几个关键指标如下:生成耗时7.8秒,其中首Token约420毫秒;语法编译一次通过;人工修改2行,共13行,占比约15%;从接需求到交付约15分钟,含人工评审;对比纯人工编写,原来45分钟起,效率提升接近3倍。整体来看,模型已经能处理大部分“费时间但不需要创造力”的编码工作,让工程师把精力留给设备安全和工艺优化。
5.4 失败案例:看起来能编译,实际会撞机的生成结果
当然也有过失败案例。我们在做机器人路径生成实验时,给模型输入“把机器人从安全点A移动到焊接点B,完成后回到安全点”,模型生成的代码语法完全正确,但漏掉了两个关键步骤:一是移动前没有把速度覆盖值设为目标速度,二是到位后没有等待伺服到位信号就直接开始焊接。如果直接在真实工作站上运行,轻则影响焊接质量,重则发生碰撞。这类问题在文本指标上看不出来,只有在仿真环境结合工艺知识才能暴露。我们把这个案例加进安全负样本集,同时调整了偏好对齐阶段的数据分布,后续模型的这类错误明显减少。这个经历让我们确定了一件事:面向工业的编码大模型,评测和护栏体系比模型本身的困惑度指标重要得多。
6. 回看这个项目,几个必须说给后来者的教训
6.1 教训一:先建评测集,再动微调
项目最开始时,我们犯过一个典型错误:数据还没整理完就急着开训练,以为训练结果能反过来指导数据清洗。结果每次改动都分不清到底是数据变好了还是模型变坏了。后来我们花两周时间先把三层评测集固化下来,之后任何一次微调、任何一次数据配比变化都有可量化的结果对照,迭代效率直接上了一个台阶。如果你的团队也要做类似项目,我强烈建议把评测集建设排在所有训练动作之前。
6.2 教训二:别指望一个模型通吃所有工业场景
工业编程的“方言”太多了:PLC的结构化文本、CNC的G代码、机器人的示教语言、SCADA的组态脚本,甚至MES里面的SQL报表,语法和上下文模型完全不是一回事。强行用一个模型学习所有方言,结果往往是每个方向都只能做到六七十分。我们后来改成“一个大模型做路由,下面挂几个领域小模型”的架构:路由器负责理解用户说的是哪个场景,再把请求交给对应领域的微调模型。虽然部署上多了几个模型服务,但每个场景的准确率提升非常明显。
6.3 教训三:工程师信任比模型分数更重要
模型评分再高,现场工程师不信任你,这个系统就是死的。我们做过一次访谈,工程师反馈最在意的不是代码生成得漂不漂亮,而是三件事:第一,代码注释是否说明了每个步骤为什么这样做;第二,生成结果是否标注了数据来源,比如“这段逻辑参考了设备手册第几节”;第三,系统是否明确告诉用户哪些操作需要人工确认。这些“可解释性”设计,比提升几个百分点的ROUGE分数更能让工程师愿意把AI建议采纳进真实工单流程。
6.4 教训四:工程投入的大头不在模型,在数据管道
如果重新估算这个项目的人力分配,模型训练和调参大概只占两成,其余八成都在做数据采集、清洗、归一化、负样本标注、回归测试和部署运维。数据管道不是一次性工作,它要求持续运转:每次客户现场产生新的程序修改、每次设备升级产生新的手册,都要回流到训练集,再触发一次评测和微调。没有这套管道,所谓的“编码大模型”只能在演示Demo里活着,进不了产线。
我个人的体会是,面向智能制造的编码大模型,本质上不是什么玄乎的新范式,而是一次把“车间里的冷门语言”从数据里重新打捞出来的工程。如果你也准备做类似的事,请务必从数据管道和评测体系开始,模型反而是整条链路里最容易迭代的部分。