ARTICLE DETAIL

资讯详情

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

智能体训练沙箱基础设施:DSec的隔离、弹性与调度实践

智能体训练沙箱基础设施:DSec的隔离、弹性与调度实践 1. 为什么智能体训练比传统训练更需要沙箱一次翻车事故引出的问题我印象很深第一次把一批智能体训练任务直接丢到公用GPU机器上跑第二天早上就被同事在群里点名了——某个探索型Agent在尝试操作环境时往/tmp下面写了一堆几十GB的中间数据把磁盘占满了另一个Agent更离谱直接调了sysctl改内核参数把整台机器的网络栈搞得不稳定。传统模型训练再怎么说前向、反向、梯度更新都是可预期的循环但智能体训练的本质是让模型学会在这个环境里行动行动必然产生副作用。这个副作用就是训练数据之外的最大变量。DSecDeepSeek弹性计算DeepSeek Elastic Computing要解决的就是这个变量。它不是我临时起意的玩具项目而是我们在支撑大规模智能体训练时沉淀下来的沙箱基础设施每个训练任务包括策略迭代、环境交互、评估回放被封装进一个独立、可弹性伸缩、可随时回收的沙箱环境里资源统一调度生命周期统一管理。这篇内容会把整体设计思路、关键实现细节和落地过程中踩过的坑逐一摊开讲适合正在做Agent训练平台、或者准备自建训练基础设施的团队参考。说得直白一点沙箱不是为了安全这个抽象概念而是为了三个非常具体的目标——让任务之间不互相污染、让单个任务不能拖垮整台机器、让每一份算力都能被按需分配和回收。后面所有设计都是围绕这三件事展开的。1.1 智能体训练与传统模型训练的差异在哪传统训练任务的压力模型是算力密集型的GPU是瓶颈数据按Batch流式进入进程内状态相对封闭。你可以用一个简单的监控脚本盯着显存和温度就行。智能体训练则完全不同它的工作负载呈现出三个传统训练没有的特征动作副作用不可枚举Agent的每一步动作都可能产生文件写入、进程创建、网络连接、系统调用。你没法提前枚举全部行为只能靠运行边界兜底。训练与推理交织策略网络既在被训练又在持续做推理决策。一个循环里可能跑几十次前向推理而且推理引擎的加载本身就需要大内存和CUDA上下文。生命周期碎片化一个完整的训练实验往往由大量子任务组成环境探索、经验回放、模型评估、对手自博弈。子任务的时长从几秒到几小时不等它们之间还有依赖关系。这些特征叠加起来意味着如果不用沙箱把任务包起来跑飞就不是概率问题而是时间问题。我们的一线训练机器上之前平均两三周就会出一次环境被搞坏的事故上了DSec之后这个频率降到了零。这就是沙箱这个设计决策最朴素的回报。1.2 沙箱的三个设计出发点隔离、弹性、可观测DSec的所有技术选型都绕不开这三个出发点我分别说一下它们在智能体训练场景下的具体含义。隔离Isolation不仅是让任务A看不到任务B的文件更重要的是单点故障隔离——某个任务把内存耗尽、把CPU跑满、把GPU显存打爆都不能拖垮同机的其他任务和宿主机器。这需要从资源配额和运行边界两个层面同时做。弹性Elasticity训练负载的波峰波谷非常剧烈。白天人多、实验多深夜可能只有几个长任务在跑。弹性要解决两件事计算资源能被动态伸缩包括横向加节点和纵向调配额以及空闲沙箱能被快速回收、把资源让给更高优先级的任务。可观测Observability沙箱把任务关起来之后监控的难度反而变大了——因为你在外面看不到里面。所以必须从第一天就把日志采集、指标暴露、状态快照设计进去否则出了问题你只能干瞪眼。1.3 明确边界沙箱不解决什么问题在深入架构之前我得先泼一盆冷水沙箱不是万能药。DSec不解决算法层面的探索效率问题不解决奖励函数设计问题也不解决模型收敛性问题。它解决的是训练跑得起来、跑得稳、资源花得值这个工程底座问题。另外还有一个务实的认知沙箱的隔离强度是有限的不是越强越好。一个需要读写CUDA设备、调GPU驱动的训练任务和你用unshare跑一个纯CPU小脚本面临的隔离约束完全不同。所以DSec没有追求一套隔离方案打天下而是做了两级隔离模型这个后面会说。2. DSec架构拆解控制面、数据面、训练支撑层各自管什么DSec的整体架构遵循一个经典思路控制与数据分离、全局调度与本地执行分层。这个思路在Kubernetes里被验证过但智能体训练的场景比普通微服务更重、更复杂所以我们在具体实现上做了不少针对性调整。整个系统可以拆成三个平面平面核心组件负责的事情控制面调度器、配额管理器、生命周期控制器、状态存储任务编排、资源分配、队列管理、状态持久化数据面Sandbox Runtime、镜像层、存储层、网络层实际运行训练任务的沙箱环境、文件读写、网络隔离训练支撑层Harness、模型仓库、数据回放服务、评估服务训练算法逻辑、模型版本管理、经验数据管理、在线评估控制面是大脑数据面是手训练支撑层是业务本身。大脑不会直接碰GPU手不会做决策业务层不关心资源怎么被调度——各司其职才能把复杂度压住。2.1 一个训练任务从提交到运行的全流程我拿一个典型的策略评估子任务来说明整个链路是怎么转起来的。Agent训练主进程通过Harness向DSec控制面提交任务描述包含镜像标识、资源需求CPU/内存/GPU、优先级、超时时间、挂载的数据集。调度器把任务放进对应优先级的队列触发调度循环。调度循环扫描各节点的可分配资源结合任务约束和节点亲和性比如某节点有闲置的A100选出目标节点。控制面通知目标节点上的Sandbox Agent启动沙箱。Sandbox Agent负责从镜像仓库拉取镜像、创建运行时隔离环境、挂载数据卷。沙箱启动后Harness的启动器在沙箱内执行训练脚本同时从控制面拉取任务级环境变量和密钥。整个运行过程中沙箱内的日志、指标、Checkpoint都通过数据面的采集通道汇聚到控制面的存储里。任务结束或超时控制面发起回收先优雅终止等待宽限期再强制销毁沙箱并释放资源。这个流程看起来不复杂但每一步都有魔鬼在细节里的地方后面几章我会逐项展开。2.2 为什么选容器作为沙箱载体而不是虚拟机或裸机聊这个是因为几乎每个来问DSec的朋友都会问一句直接用KVM虚拟机隔离不更干净吗确实更干净但代价你未必付得起。虚拟机的代价启动时间以秒甚至分钟计镜像动辄几个GB到几十GBGPU直通配置复杂一台物理机上能同时跑的虚拟机数量远少于容器。智能体训练有大量分钟级甚至秒级的短任务用虚拟机跑短任务的资源浪费是非常可观的。裸机的代价没有隔离任务之间互相踩踏。前面说的磁盘打满、内核参数被改都是裸机的经典翻车现场。容器的位置启动时间毫秒级镜像可以做到几百MB到几个GB支持GPU设备注入单机上能跑的实例数多一个量级。它的问题在于内核共享——恶意或者故障的容器可以尝试攻击宿主内核但训练场景里绝大多数搞破坏不是恶意攻击而是失控不是蓄意入侵。失控用cgroup、命名空间和系统调用过滤就足够挡住大部分了。当然容器隔离确实有天花板。所以在DSec里对于风险等级高的任务比如要从网上下载不可信代码、要执行外部工具的我们会升级到第二级隔离。这个组合策略性价比最高的方案。你不需要用防弹玻璃保护一个只需要防尘的房间。2.3 控制面前置的资源配额模型资源配额是整个弹性的基石我单独说一下它的数学逻辑。DSec的资源配额不是简单的每任务给多少而是按账户/项目/队列三层管理账户层每个实验团队一个账户设定总资源上限防止某个团队把所有算力吃光。项目层每个项目组在账户下有项目级配额支持共享和预留。队列层每个队列绑定一组配额任务按优先级在队列内排队。计算公式上一个节点的可分配资源不是简单把物理资源加起来而是一个动态可超卖模型可分配CPU 物理CPU核数 × 超卖系数默认1.5 可分配内存 物理内存 × 0.9预留10%给系统与沙箱运行时 可分配GPU 物理GPU数 × 设备分片粒度支持MIG或时间片共享超卖系数1.5意味着我们会让CPU配额的总量超过物理核数。为什么敢超卖因为智能体训练任务里有大量IO等待和决策间隙CPU实际使用率远低于配额。但要配套一个严格的真实使用率监控一旦节点整体CPU使用率超过85%调度器就会停止向该节点分配新任务宁可排队也不让过载。这是我们在实际运行中总结出的一个关键经验超卖是必要的但必须有一个硬性过载保护阀值不然遇到一批CPU密集的探索任务会集体崩盘。3. 弹性不是越多越好队列感知调度与训练阶段伸缩的实操逻辑听多了弹性伸缩这个词的人容易把弹性简单理解成负载高了就加机器、低了就减机器。在DSec里这个理解只对了一半。智能体训练的弹性有两个层次处理不好就会造成资源闲置或者任务饿死。3.1 两个层次的弹性诉求任务级弹性指单个训练任务内部的并行度可以变化。比如一个策略评估任务本来用4个并行环境队列一紧可以降到2个甚至挂起等资源队列空闲了再恢复4个甚至扩到8个。这个诉求在传统训练里很少见——你不可能让一个梯度下降过程挂起再恢复但智能体训练的任务大多是经验采集、评估、子博弈这类天然支持挂起恢复。资源级弹性指整个资源池的大小可以变化。包括在裸金属集群里动态拉起/下线K8s节点、在云上开/关实例、以及在同一节点内部调整各沙箱的资源配额。听起来复杂实际落地时我们优先做的是后两种因为团队大部分算力是自有硬件。3.2 队列调度与优先级抢占逻辑DSec的调度器核心是一个多级反馈队列MLFQ的变体与通用调度器不同的是它必须感知训练任务的阶段特征。优先级的设定规则我直接列出来P0最高在线评估、正在逼近截止期的重要实验、人工交互调试任务。P1常规训练迭代、经验采集、模型评估。P2批量离线实验、数据预计算、模型对比跑分。P3最低实验性探索、无截止期的扫描式任务。调度逻辑有一个关键的抢占设计P0任务到达时如果资源不够不会直接杀掉P3任务杀任务有Checkpoint成本而是先做挂起。挂起一个沙箱的成本远低于销毁重建进程被冻结、内存页可以被换出、GPU上下文被保存。等P0跑完再恢复。这个机制是我们弹性的核心之一实际体验下来挂起恢复一个带GPU上下文的任务大概需要2到5秒相比重新初始化要快一个数量级。优先级抢占还必须配合一个安全阀同一个账户下的P0任务数量不能超过该账户总配额的20%防止高优任务把整个池子锁死。这个限制我们在线上调过多次最终定在20%是平衡了急活优先和整体吞吐两个指标的结果。3.3 伸缩触发条件不只看负载还要看任务画像决定伸缩策略时我们踩过一次伪负载的坑。当时监控显示某节点CPU利用率只有10%调度器就疯狂往里塞任务结果新任务一进来CPU直接窜到100%然后一批任务的QPS全崩了。原因是我们监控的是申报使用率任务请求的配额利用率而不是实测使用率cgroup真实统计的CPU时间。后来我们把伸缩触发条件改成一套多维判断任何单一指标都不能触发伸缩指标触发条件说明队列积压深度队列中等待任务数持续超过10个且平均等待超30秒说明资源供给跟不上需求节点实测CPU节点整体cpuacct.usage超过85%持续5分钟过载保护触达则停止新任务分配节点实测内存内存水位超过90%且持续3分钟防止OOM风暴尤其是GPU任务的显存溢出GPU利用率某个训练阶段如经验采集GPU利用率低于40%持续10分钟触发资源压缩或任务合并训练阶段感知任务进入收敛期loss变化率小于阈值时自动释放部分并行度把资源让给长尾的新任务最后一条训练阶段感知是我个人比较得意的一个设计因为智能体训练天然分阶段探索阶段需要大量并行环境采样收敛阶段对算力的需求会指数级下降。Harness会在训练循环里周期性上报当前阶段给DSec控制面调度器据此动态调整并行环境数量。这个机制实际运行中能省下大概30%的GPU资源用于喂给其他排队任务。3.4 冷启动优化三件套镜像预热、Sandbox复用、增量快照弹性伸缩最大的敌人是冷启动延迟。如果一个任务要等3分钟才能开始跑那么弹得再快也没用。我们把这3分钟拆解成了三块镜像拉取、沙箱创建、工作目录初始化。逐个优化。镜像预热每个节点上运行一个预热Daemon周期性从镜像仓库拉取最近24小时内使用过的镜像并保持在本地。实测下来预热后的镜像启动时间从几十秒降到秒级。这里有个小技巧预热不要只拉latest要拉带SHA256摘要的精确版本否则镜像更新后本地缓存全部失效。Sandbox复用一个沙箱销毁后它的基础环境根文件系统、运行时配置、已加载的CUDA库并不会完全删除而是保存为一个温池状态。新任务进来如果镜像和运行时要求与温池里的沙箱匹配直接从温池拉起省掉了内核命名空间初始化和CUDA库加载。这个优化让沙箱创建时间平均压到了600毫秒以内。增量快照训练任务的工作目录通过OverlayFS挂载每次Checkpoint只保存文件系统层的增量diff而不是整份目录。这个设计让挂起/恢复、以及跨节点迁移的开销都大幅下降。后面第5章会详细展开。4. 隔离强度不是单选题两级隔离模型与权限坑开头我说过DSec不做一套隔离方案打天下具体来说就是两级模型。第一级是我们日常使用的标准做法第二级是针对高风险任务的兜底方案。这一章除了设计思路我还会把权限方面踩过的坑一并倒出来因为它们非常隐蔽、非常容易复发。4.1 第一级内核命名空间cgroup的轻量隔离DSec的第一级隔离基于标准Linux容器语义但在几个细节上做了加固命名空间隔离每个沙箱独立PID、Mount、Network、UTS、IPC命名空间。PID隔离保证沙箱内的进程看不到宿主机进程这除了安全考虑还有一个工程上的好处沙箱内进程号从1开始很多训练框架的进程管理逻辑会很自然地工作。cgroup v2资源控制CPU配额用cpu.max限制内存用memory.high和memory.max双阈值。双阈值的意义是memory.high先触发软限流让进程开始降速而不是直接被杀超过memory.max才触发OOM Kill。这对训练任务非常友好——很多框架对OOM的处理是直接崩溃但如果只是限流它自己能通过GC或降低批大小缓过来。系统调用过滤使用seccomp配置默认过滤掉mount、reboot、kexec_load、swapon等危险调用。注意这里用的是过滤高风险调用而不是白名单只放指定调用因为训练框架尤其涉及CUDA、MPI的版本经常有未知的系统调用需求白名单模式会误伤到你想不到的地方。文件系统隔离沙箱根文件系统为只读工作目录用OverlayFS挂载为读写临时目录用tmpfs。这个设计的核心动机是就算任务把整个系统目录写满了也只是把OverlayFS的上层写满宿主机没有影响。4.2 第二级微虚拟机兜底真实不可信任务有些任务你必须假定它可能不怀好意而不是失控。比如让Agent从公开网络下载并执行一段外部代码来测试它的工具使用能力这种情况下容器隔离就不够用了。DSec的第二级隔离引入了用户态内核运行时和轻量微虚拟机每次执行都用一个全新的虚拟化实例任务结束即销毁。这个级别的性能开销确实存在我们测过纯计算损耗约5%到10%GPU直通场景损耗可以控制在3%以内但换来的是TaggedTLB级别的内核级隔离。它的配置与容器隔离在DSec里是完全透明的任务声明里多一个isolationLevel: strong字段即可。训练支撑层不用感知这个差别。4.3 权限系统的常见坑从文件权限到Windows特有API权限问题在训练沙箱里出现频率比很多人预想的要高得多而且往往不是安全攻防层面的问题就是纯工程配置的粗心。我列几个典型场景。坑一Harness的Skill读取文件报权限错误。在使用Harness插件尤其是文件检索类Skill时沙箱内路径/workspace通常属于root训练进程如果以普通用户运行就会吃到类似Permission denied的错误。很多人的第一反应是chmod 777简单粗暴但在训练环境里这会让跨任务隔离的数据泄露面变大。正确做法是在沙箱创建时通过--user参数指定非root运行然后把挂载数据卷的所有者显式改为该用户。这个配置做在镜像里而不是启动时临时改。坑二Windows环境的SetNamedSecurityInfoW失败Win32错误5访问被拒绝。这不是Linux端的坑是我们用商店版PowerShell实际跑DSec命令时碰到的。问题根源是商店版PowerShell受AppContainer机制限制调用Windows安全API修改文件ACL时会被系统拦截。当时排查了很久最后解决方案是换用系统自带的Windows PowerShell 5.1或者先用icacls刷新一遍目标目录的ACL再调用。这个坑说明沙箱管理工具链本身也要遵守宿主平台的运行边界尤其是Windows上沙箱嵌套沙箱的场景。坑三只读根文件系统上的缓存目录。很多深度学习框架HuggingFace、pytorch扩展默认把缓存写到/root/.cache而沙箱根文件系统是只读的。如果不在构建镜像时把HF_HOME、TORCH_HOME这些环境变量指到/workspace/.cache启动就会卡在下载或缓存写入环节而且报错信息非常误导人往往看起来像网络问题。我们后来在Harness的基础镜像里预置了完整的缓存环境变量集这类问题才绝迹。4.4 逃逸边界与风险假设作为一个做基础设施的团队必须对隔离为什么不会被突破保持清醒。我明确说明DSec的风险假设边界第一级容器隔离假设任务行为是失控而非恶意。它防不住一个真正意图逃逸的攻击者所以绝不将敏感数据或跨租户密钥注入低隔离级别的沙箱。第二级微虚拟机隔离假设出厂内核无高危0day。所有系统软件保持更新策略。考虑到训练任务的时效性这个更新节奏是每月一次靠自动化流水线完成。两种隔离级别都不防范有特权的本机管理员这是所有租户隔离系统的共同前提不需要特别解释。5. 沙箱里的数据怎么活快照、回放与产物回收策略训练任务的数据流动是沙箱设计里最容易被低估的部分。很多平台把精力都花在隔离和调度上结果训练到一半想恢复、想回看关键片段发现数据全被清掉了。DSec在数据生命周期上的设计原则是三句话数据可恢复、过程可回放、产物可回收。5.1 写时复制与沙箱文件系统的层次设计每个沙箱的文件系统由三层构成基础镜像层只读操作系统、训练框架、依赖库。用户数据层只读挂载数据集、预训练权重、共享缓存通过内容寻址存储CAS按内容去重多个沙箱共享同一份数据不占额外空间。工作层可写OverlayFS的上层训练中产生的所有写入都在这里。工作层仅在沙箱存活期间存在销毁时可以选择保留为快照或彻底删除。OverlayFS的写时复制机制让几百个沙箱共享同一个100GB数据集成为可能每个沙箱实际只是在虚拟文件系统层做了一层薄薄的影子。这个设计在用户数据动辄几十上百GB的智能体训练场景里是刚需否则光数据拷贝就能把网络和磁盘打爆。5.2 Checkpoint与训练进度恢复智能体训练的Checkpoint不只是模型权重还包括环境状态、经验回放缓冲区、评估历史。DSec的Checkpoint策略支持两种模式定时快照默认每15分钟对工作层做一次增量快照。增量快照只记录自上次快照以来修改过的文件块存储成本很低。关键事件触发Harness可以在业务关键节点如策略更新完成、一轮评估结束主动调用DSec API触发快照。这个模式对挂起后恢复非常关键——比如一个P0任务抢占时P3任务被挂起恢复时只需要回到最近一次关键事件的状态不用从头跑。恢复流程我给出一个实际数字一个包含200GB工作目录的沙箱从快照恢复到完全可用状态平均耗时约40秒其中20秒是OverlayFS层的合并8秒是GPU上下文恢复其余是环境初始化和探针检查。作为对比不恢复直接重新启动同样任务需要约20分钟。差距非常直观。5.3 产物回收与证据链训练任务跑完后产物的处理策略决定了资源能不能及时释放。DSec有一个回收优先级的概念模型权重和评估报告立即归档到模型仓库标记版本号。训练日志和指标压缩后进入冷存储保留30天。中间数据和临时文件如果任务正常结束立即删除如果任务异常终止保留24小时供排查然后自动清理。原始经验数据按项目配置决定保留或删除默认保留一个抽样子集用于后续分析。还有一个容易被忽略的证据链需求当训练效果不符合预期你需要能回溯到那批数据、那个版本、那组超参数是怎么来的。所以DSec对每个训练任务都生成一组固定的元数据任务ID、镜像版本、数据集版本、代码Commit、随机种子、资源配额这些元数据随产物一起归档。没有这层设计后续复现实验时你会发现根本说不清楚当时的实验条件。5.4 数据标注与训练数据准备这个不算DSec的核心功能但训练数据环节经常被沙箱忽略。我们的习惯是把数据标注和清洗任务也跑在DSec沙箱里而不是让标注人员在公共环境直接操作。原因很简单——标注脚本经常包含一次性、未经验证的解析逻辑极易产生脏数据和不一致的数据格式。在沙箱里跑就算脚本质量差也不会污染正式的数据集目录跑完直接丢弃即可。数据样例和标注结果统一通过数据层写入CAS存储后续训练任务以只读方式挂载引用从源头上切断了训练数据被训练任务改动的可能。6. Harness工具链让训练任务可编排、可回退、可插拔DSec的弹性计算底座之上真正与算法工程师每天打交道的是Harness——一套负责训练任务编排、指令投喂、插件扩展和质量迭代的工作流工具。这一章说的Harness可能和你在网上看到的一些同名工具有一定关联但这里的描述是我们在DSec体系内沉淀下来的实际用法。6.1 Harness在DSec中的定位如果说DSec是操作系统Harness就是运行在操作系统上的业务框架。它负责把一次智能体训练实验拆成可编排的步骤并把每一步映射到DSec的沙箱生命周期上。一个典型的Harness工作流长这样准备阶段从模型仓库拉指定版本的基础策略权重从数据仓库挂载训练数据集。训练阶段启动策略更新循环。每轮更新后发起一批评估任务到DSec队列等待结果回收。评估阶段评估任务在独立沙箱里跑产出胜率、奖励曲线、轨迹可视化等指标。决策阶段根据评估结果由人工或自动规则决定是继续训练、调整超参数、还是回退到之前的模型版本。这个流程里DSec负责每一个步骤的资源供给和隔离Harness负责步骤之间的逻辑编排和状态管理。两者接口通过GRPC和一份任务声明文件对接声明文件格式类似于下面这样workflow: policy_iteration_v3 model: repo: models://research/ppo/experiment_2025x version: v12 data: mount: datasets://soccer/sim_v2 tasks: - name: collect_experience num_replicas: 16 runtime: { isolation: standard, gpu: 0.5 } - name: evaluate num_replicas: 8 runtime: { isolation: strong, gpu: 0.25 } policy_update: metric: win_rate threshold: 0.55 fallback: v116.2 任务状态机与错误自动回退训练任务的状态机设计决定了对异常的处理是否优雅。DSec里每个任务的状态流转是Pending - Running - Suspended - Running - Terminated \ \ / \--------------------\-------------------/ Failed关键在三个状态的语义Pending排队等资源。此时不消耗算力只消耗队列空间。Running沙箱已创建训练进程跑在沙箱内。Suspended被更高优先级任务抢占沙箱冻结等待恢复。异常处理方面Harness有一套默认的回退策略训练循环内如果连续三轮评估结果低于历史最优会自动回退到最近一个效果可接受的模型版本而不是继续空转消耗算力。这个策略看起来像算法层面的东西但它必须依赖DSec的任务元数据才能实现——因为Harness需要拿到历史快照和Checkpoint版本列表而这些信息由DSec统一存储和暴露。我自己体会最深的是这个状态机的失败快照能力当一个任务Failed时DSec自动保留一个失败环境的完整快照包括当时的训练日志、最后一条状态、所有线程的堆栈。这一步让调试一次性事故的成本大幅下降。很多训练平台的失败诊断只给一段日志但缺少当时的环境上下文排查效率极低。DSec的失败快照基本上把复现问题变成了打开快照看现场。6.3 插件机制与提示词优化智能体训练里Agent的决策提示词Prompt优化是一个实际存在的需求尤其当Agent内置了LLM推理模块时。Harness支持插件机制我们内部用得最多的插件类型就是提示词优化器和评估器。提示词优化插件做的事情是把一次训练中不同迭代轮次的Prompt版本、对应的Agent行为统计、评估结果都记录下来然后用对比实验的方式给出哪个版本的效果更好。它的本质是一个覆盖变化-行为-结果的因果追踪工具底层数据来自DSec的任务元数据和评估服务的指标。插件开发接口我们设计得尽量薄一个插件本质就是一个遵守协议的可执行文件# harness plugin protocol class HarnessPlugin: def on_task_start(self, task_ctx): ... def on_step_end(self, step_ctx): ... def on_episode_end(self, episode_ctx): ... def on_task_end(self, task_ctx): ...这个协议简单到几乎所有语言都能实现实际社区里已经有Python、Go、Rust几个版本。插件的运行也在沙箱内权限受限于所在任务的隔离级别不允许插件之间互相访问。这保证了第三方插件的安全性边界是明确的。6.4 外部Agent客户端接入API调用与其他编码工具集成智能体训练平台不是孤岛算法工程师日常还大量使用外部客户端来调试和驱动训练。最常见的是两类一类是直接API调用。DSec对外提供一套面向任务的API支持创建、查询、暂停、恢复、销毁任务。API风格是RESTful认证使用Bearer Token。一个简单的调用示例# 提交一个训练任务 curl -X POST https://dsec.example.com/v1/tasks \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ -d { workflow: policy_iteration_v3, num_replicas: 4, runtime: {isolation: standard, gpu: 0.5} }另一类是编码工具的集成。团队里有人用Codex、Claude Code这些工具编写训练脚本和策略代码他们会把这工具指向DeepSeek的模型服务作为后端然后在代码里调用DSec的API把训练任务提交到沙箱。这类接入本质上就是一个大模型生成代码 → 代码提交到沙箱 → 沙箱执行并回报结果的闭环。DSec在实现上只需要保证API稳定、返回结构清晰其余不需要做任何额外适配。7. 离线与内网部署落地没有外网也能跑起来的要点DSec的设计目标里有一条很明确沙箱训练基础设施必须能在没有外网的隔离环境里运转。不管是因为数据合规要求还是因为机房网络架构限制内网落地都是刚需。而且这个需求不是少数——很多企业级训练环境都是完全禁止出网的。7.1 离线镜像与依赖同步方案沙箱的基础是一切依赖提前打包进镜像所以离线环境的第一步是把镜像仓库整个同步进内网。我们在实践中用的方案是在能联网的构建机上把所有依赖基础操作系统镜像、Python依赖、CUDA驱动、训练框架、Harness运行时构建成完整的沙箱镜像。用docker save或skopeo copy导出为本地存档文件。将存档文件通过物理介质或内网传输工具导入内网镜像仓库。在内网镜像仓库启动定期清理策略只保留最近N天使用过的镜像版本防止磁盘被历史镜像塞满。这里有个容易被忽略的坑Python依赖的传递依赖。很多人在构建镜像时只装了顶层依赖运行时才发现某个传递依赖没装而在离线环境里想补装几乎不可能。我们的规避手段是构建时统一用带锁定的依赖解析方案生成完整依赖列表再在镜像构建阶段做一次全量安装验证。宁可构建慢一点也要保证镜像里完整。7.2 内网DNS、证书与代理配置离线环境里沙箱的网络配置有三大件DNS、证书、代理如果内网有统一的出网代理。DNS沙箱内的/etc/resolv.conf必须指向内网DNS服务器。要是沙箱默认用了宿主的systemd-resolved配置而内网DNS不支持某些递归查询会出现间歇性的域名解析失败。我们的做法是在沙箱创建时强制注入内网DNS配置而不是继承宿主配置。证书内网环境常用自建CA签发的证书而许多训练框架在下载依赖时用Python的ssl模块默认不信任自建CA。解决方案是构建镜像时把内网CA证书添加到系统信任库同时设置REQUESTS_CA_BUNDLE和SSL_CERT_FILE环境变量指向它。这个问题之所以隐蔽是因为它会随机出现在某些库的HTTPS调用里报错五花八门很难一眼看出是证书问题。7.3 小规模环境的资源裁剪DSec完整版需要至少三台机器跑控制面高可用。但不少小团队只有一台高配GPU服务器这时候也不用放弃沙箱化可以做资源裁剪控制面合并调度器、生命周期控制器、状态存储可以全压在同一台机器上只要把API服务的副本数降为1关掉高可用相关组件。控制面本身对资源要求不高CPU 4核、内存8GB就够。去掉K8s依赖如果有我们最初用K8s做节点管理但在单机场景里K8s太重了。裁剪版DSec直接用节点上的Sandbox Agent拉起沙箱用文件锁做简单的单机调度。少了容器编排层的开销单机上的资源利用率和启动速度反而更快。关闭镜像预热单机上没有多节点竞争的拉镜像压力预热反而浪费磁盘空间。裁剪版和完整版共用同一份任务声明文件只是部署包不同。从完整版迁移到裁剪版算法工程侧的感受是无感的。7.4 部署后的验证清单每次内网部署完我会按下面这份清单做验收推荐你也照着查一遍提交一个CPU小任务确认沙箱能创建、运行、退出。提交一个带GPU任务用nvidia-smi确认显存分配和CUDA上下文正常。验证文件系统只读/可写区确认根文件系统只读工作目录可写。验证数据卷挂载确认数据集以只读方式挂载且多个任务可共享。模拟一次资源超限将任务的cgroup内存限制故意调小确认任务被限流或OOM宿主机器不受影响。验证优先级抢占提交一个P0任务挤占P3任务确认P3被挂起后能恢复。验证失败快照故意让任务崩溃确认失败环境的快照可访问。这一整套走下来大约需要半天但它能帮你避免上了生产才发现沙箱配置有问题的尴尬。我在几次实际部署中发现大部分问题都出在GPU驱动与沙箱运行时的兼容性上所以第2步值得反复多测几遍。
返回列表