dsh-eval-guard 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/neural-pendulum/SPEC.md +470 -0
- package/assets/neural-pendulum/TASK.md +360 -0
- package/assets/neural-pendulum/hidden/test_infra.cpp +631 -0
- package/assets/neural-pendulum/include/nn/nn.hpp +88 -0
- package/assets/neural-pendulum/sim.cpp +126 -0
- package/assets/neural-pendulum/sim_eval +0 -0
- package/assets/neural-pendulum/workspace.zip +0 -0
- package/eval/neural-pendulum.py +15 -0
- package/lib/client/index.js +41 -4
- package/lib/client/index.js.map +1 -1
- package/lib/index.js +454 -60
- package/neural-cifar-eval/README.md +57 -0
- package/neural-cifar-eval/cifar_cache.py +201 -0
- package/neural-cifar-eval/common.py +67 -0
- package/neural-cifar-eval/fetch_cifar.py +31 -0
- package/neural-cifar-eval/hidden/.gitkeep +1 -0
- package/neural-cifar-eval/ops_eval.py +502 -0
- package/neural-cifar-eval/run_eval.py +208 -0
- package/neural-pendulum-eval/run_eval.py +302 -0
- package/neural-pendulum-eval/sim_eval +0 -0
- package/package.json +4 -2
- package/eval/__pycache__/common.cpython-310.pyc +0 -0
- package/eval/__pycache__/neural-cifar.cpython-310.pyc +0 -0
- package/eval/__pycache__/neural-fp32.cpython-310.pyc +0 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# Neural-Pendulum 任务规格 v1.3
|
|
2
|
+
|
|
3
|
+
本文件是已确定的任务内部规格。实现、评测器、workspace 素材以此为准。
|
|
4
|
+
后续除非明确修改规格,否则不再重新讨论这些规则。
|
|
5
|
+
|
|
6
|
+
## 1. 任务标识
|
|
7
|
+
|
|
8
|
+
- task id: neural-pendulum
|
|
9
|
+
- 中文名: Neural-Pendulum · 从零神经网络基础设施与双驱动三阶摆控制
|
|
10
|
+
- 形态: 单个 agent 在独立工作区内完成源码实现并多次提交/测试
|
|
11
|
+
- 语言: C++17、仅 CPU、fp32
|
|
12
|
+
- 最终交付: 源码(不提交编译产物)
|
|
13
|
+
|
|
14
|
+
## 2. 任务目标
|
|
15
|
+
|
|
16
|
+
agent 必须:
|
|
17
|
+
|
|
18
|
+
1. 从零实现一套神经网络基础设施(张量、算子、反向传播、优化器、模型序列化、线程池)。
|
|
19
|
+
2. 使用该基础设施训练一个神经网络控制器。
|
|
20
|
+
3. 控制预编译双驱动三节摆:第一、第三关节施加有限力矩,中间关节被动,从全向下起摆,并保持三根杆全部向上至少 t_tgt = 10.0 s。
|
|
21
|
+
4. 保证基础设施实现 `include/nn/nn.hpp` 契约并通过隐藏测试。
|
|
22
|
+
5. 提交的源码中不得出现 torch,测试环境不提供 Python/torch。
|
|
23
|
+
|
|
24
|
+
允许在开发阶段使用 PyTorch 做数值自查和参考,但提交源码必须完全独立。
|
|
25
|
+
|
|
26
|
+
## 3. 被控对象
|
|
27
|
+
|
|
28
|
+
三节平面欠驱动摆:
|
|
29
|
+
|
|
30
|
+
- 3 根均匀杆
|
|
31
|
+
- 第一关节、第三关节受控;第二关节被动
|
|
32
|
+
- 控制量: 两个归一化力矩 [u1, u3],每个 in [-1, 1]
|
|
33
|
+
- 物理力矩: tau_1 = u1 * tau_max,tau_3 = u3 * tau_max,tau_2 = 0
|
|
34
|
+
- 控制频率: 100 Hz,控制周期 dt = 0.01 s
|
|
35
|
+
- 每个控制周期内部用 4 个 RK4 子步
|
|
36
|
+
- 最大仿真时长: 30.0 s
|
|
37
|
+
|
|
38
|
+
固定物理参数(环境内部隐藏,不向 agent 暴露):
|
|
39
|
+
|
|
40
|
+
~~~
|
|
41
|
+
m = [1.0, 1.0, 1.0] kg
|
|
42
|
+
l = [0.5, 0.5, 0.5] m
|
|
43
|
+
r = [0.25, 0.25, 0.25] m
|
|
44
|
+
I = m * l^2 / 12
|
|
45
|
+
g = 9.81 m/s^2
|
|
46
|
+
joint damping = 0.01
|
|
47
|
+
tau_max = 18.0 N m(每个驱动关节独立限制)
|
|
48
|
+
~~~
|
|
49
|
+
|
|
50
|
+
角度约定:
|
|
51
|
+
|
|
52
|
+
- theta_i = 0 表示第 i 根杆竖直向下
|
|
53
|
+
- theta_i = pi 表示竖直向上
|
|
54
|
+
- 所有角度为绝对角度
|
|
55
|
+
|
|
56
|
+
末端位置:
|
|
57
|
+
|
|
58
|
+
~~~
|
|
59
|
+
x_tip = sum_i l_i * sin(theta_i)
|
|
60
|
+
y_tip = -sum_i l_i * cos(theta_i)
|
|
61
|
+
~~~
|
|
62
|
+
|
|
63
|
+
## 4. 初始状态
|
|
64
|
+
|
|
65
|
+
训练仿真环境每次 reset 不加固定偏差,只加噪声:
|
|
66
|
+
|
|
67
|
+
~~~
|
|
68
|
+
theta_i ~ Uniform(-0.05, 0.05) rad i = 1,2,3,独立采样
|
|
69
|
+
omega_i ~ Uniform(-0.02, 0.02) rad/s i = 1,2,3,独立采样
|
|
70
|
+
~~~
|
|
71
|
+
|
|
72
|
+
即三根杆接近全向下,初始角度以全向下为中心随机扰动。
|
|
73
|
+
|
|
74
|
+
评测环境使用固定初始状态:
|
|
75
|
+
|
|
76
|
+
~~~
|
|
77
|
+
theta = [0.013, -0.008, 0.021] rad
|
|
78
|
+
omega = [0, 0, 0]
|
|
79
|
+
~~~
|
|
80
|
+
|
|
81
|
+
三个固定角互不相同,且绝对值互不相同。
|
|
82
|
+
|
|
83
|
+
评测期间不加入任何随机扰动。
|
|
84
|
+
|
|
85
|
+
## 5. Agent 观测
|
|
86
|
+
|
|
87
|
+
控制器每一步只获得三个关节角度:
|
|
88
|
+
|
|
89
|
+
~~~
|
|
90
|
+
a_i = wrap_to_pi(theta_i - pi) i = 1,2,3
|
|
91
|
+
obs = [a1, a2, a3] (rad)
|
|
92
|
+
~~~
|
|
93
|
+
|
|
94
|
+
即 3 维浮点向量,单位 rad,不除以 pi。
|
|
95
|
+
|
|
96
|
+
- theta_i 为绝对角度
|
|
97
|
+
- a_i 为相对竖直向上的角度误差
|
|
98
|
+
- 不提供角速度
|
|
99
|
+
- 不提供第三杆末端位置
|
|
100
|
+
- 不提供杆长/质量/惯量/真实物理参数
|
|
101
|
+
|
|
102
|
+
控制器必须自行从角度历史构造任何需要的速度、差分或其他内部状态;不强制任何模型结构。
|
|
103
|
+
|
|
104
|
+
## 6. 动作
|
|
105
|
+
|
|
106
|
+
控制器输出两个归一化力矩:
|
|
107
|
+
|
|
108
|
+
~~~
|
|
109
|
+
[u1, u3] ∈ [-1, 1]^2
|
|
110
|
+
~~~
|
|
111
|
+
|
|
112
|
+
映射:
|
|
113
|
+
|
|
114
|
+
~~~
|
|
115
|
+
tau_1 = u1 * tau_max
|
|
116
|
+
tau_3 = u3 * tau_max
|
|
117
|
+
tau_2 = 0
|
|
118
|
+
~~~
|
|
119
|
+
|
|
120
|
+
非有限值、超范围或格式错误:
|
|
121
|
+
|
|
122
|
+
~~~
|
|
123
|
+
stage = controller
|
|
124
|
+
score = -1
|
|
125
|
+
~~~
|
|
126
|
+
|
|
127
|
+
## 7. 训练仿真接口
|
|
128
|
+
|
|
129
|
+
工作区提供预编译 tools/sim,不提供源码和内部参数。
|
|
130
|
+
环境只提供状态转移,不提供 reward、loss、cost 或 done 信号。训练信号由 agent 自行构造。
|
|
131
|
+
|
|
132
|
+
优化目标:
|
|
133
|
+
|
|
134
|
+
~~~
|
|
135
|
+
从接近全向下的初始状态起摆
|
|
136
|
+
使三根杆全部进入竖直向上容差并尽可能长时间保持
|
|
137
|
+
评测指标为 t_can
|
|
138
|
+
~~~
|
|
139
|
+
|
|
140
|
+
不规定损失函数、奖励函数、优化器或训练算法。
|
|
141
|
+
|
|
142
|
+
JSONL 协议:
|
|
143
|
+
|
|
144
|
+
输入:
|
|
145
|
+
|
|
146
|
+
~~~json
|
|
147
|
+
{"cmd":"reset"}
|
|
148
|
+
{"cmd":"step","torque":[0.5,-0.5]}
|
|
149
|
+
~~~
|
|
150
|
+
|
|
151
|
+
输出:
|
|
152
|
+
|
|
153
|
+
~~~json
|
|
154
|
+
{"obs":[3 floats]}
|
|
155
|
+
~~~
|
|
156
|
+
|
|
157
|
+
每个 episode 最多 3000 步(30.0 s)。
|
|
158
|
+
|
|
159
|
+
达到最大步数后再发送 step:
|
|
160
|
+
|
|
161
|
+
~~~json
|
|
162
|
+
{"error":"episode_finished"}
|
|
163
|
+
~~~
|
|
164
|
+
|
|
165
|
+
此时不会返回新的观测,也不会继续推进仿真。
|
|
166
|
+
必须发送 reset 才能开始新 episode;reset 之前的所有 step 都返回该错误。
|
|
167
|
+
|
|
168
|
+
## 8. 交付源码与构建
|
|
169
|
+
|
|
170
|
+
只提交源码,不提交可执行文件。
|
|
171
|
+
|
|
172
|
+
源码根目录必须支持:
|
|
173
|
+
|
|
174
|
+
~~~
|
|
175
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
|
176
|
+
cmake --build build -j4
|
|
177
|
+
~~~
|
|
178
|
+
|
|
179
|
+
必须产生:
|
|
180
|
+
|
|
181
|
+
~~~
|
|
182
|
+
build/libnn.a
|
|
183
|
+
build/control
|
|
184
|
+
~~~
|
|
185
|
+
|
|
186
|
+
### 8.1 基础设施测试入口
|
|
187
|
+
|
|
188
|
+
基础设施实现位于 `src/nn/*.cpp`,由 CMake 构建静态库 `build/libnn.a`;公开头文件 `include/nn/nn.hpp` 为不可修改的 API 契约。
|
|
189
|
+
|
|
190
|
+
评测侧独立编译隐藏测试并链接 `build/libnn.a`,不以 `build/nn_selftest` 作为通过依据;`nn_selftest` 仅供 agent 自测。
|
|
191
|
+
|
|
192
|
+
隐藏测试覆盖:
|
|
193
|
+
|
|
194
|
+
- fp32 tensor、形状与广播
|
|
195
|
+
- elementwise add/sub/mul/div
|
|
196
|
+
- matmul / linear
|
|
197
|
+
- relu / softmax
|
|
198
|
+
- layernorm
|
|
199
|
+
- conv2d(stride/padding/dilation/groups)
|
|
200
|
+
- MSE
|
|
201
|
+
- matmul/linear/relu/layernorm/conv2d/MSE 反向
|
|
202
|
+
- SGD momentum
|
|
203
|
+
- AdamW
|
|
204
|
+
- 模型保存/加载
|
|
205
|
+
- 线程池
|
|
206
|
+
|
|
207
|
+
任一测试失败:
|
|
208
|
+
|
|
209
|
+
~~~
|
|
210
|
+
stage = infra
|
|
211
|
+
score = -1
|
|
212
|
+
~~~
|
|
213
|
+
|
|
214
|
+
占位符返回空结果按错误处理。
|
|
215
|
+
|
|
216
|
+
### 8.2 控制器入口
|
|
217
|
+
|
|
218
|
+
build/control 是一个常驻进程,使用 JSONL 协议:
|
|
219
|
+
|
|
220
|
+
输入:
|
|
221
|
+
|
|
222
|
+
~~~json
|
|
223
|
+
{"type":"reset"}
|
|
224
|
+
{"type":"step","step":0,"state":[3 floats]}
|
|
225
|
+
~~~
|
|
226
|
+
|
|
227
|
+
输出:
|
|
228
|
+
|
|
229
|
+
~~~json
|
|
230
|
+
{"type":"ready"}
|
|
231
|
+
{"type":"action","torque":[0.5,-0.5]}
|
|
232
|
+
~~~
|
|
233
|
+
|
|
234
|
+
规则:
|
|
235
|
+
|
|
236
|
+
- 每次测试启动一个新进程
|
|
237
|
+
- 先 reset,必须回复 ready
|
|
238
|
+
- 每个 step 必须在 100 ms 内回复
|
|
239
|
+
- 控制器可保存自己的历史状态
|
|
240
|
+
- 控制器崩溃、超时、非法输出:stage = controller,score = -1
|
|
241
|
+
|
|
242
|
+
## 9. 评测测量
|
|
243
|
+
|
|
244
|
+
固定:
|
|
245
|
+
|
|
246
|
+
~~~
|
|
247
|
+
dt = 0.01 s
|
|
248
|
+
最大仿真 = 30.0 s
|
|
249
|
+
t_tgt = 10.0 s
|
|
250
|
+
全向上容差 = 每根杆与竖直方向夹角 <= 0.05 rad
|
|
251
|
+
~~~
|
|
252
|
+
|
|
253
|
+
t_can 定义:
|
|
254
|
+
|
|
255
|
+
~~~
|
|
256
|
+
从 reset 开始,三根杆全部处于容差内的最长连续时间
|
|
257
|
+
从未出现全向上则 t_can = 0
|
|
258
|
+
~~~
|
|
259
|
+
|
|
260
|
+
计分用的截断:
|
|
261
|
+
|
|
262
|
+
~~~
|
|
263
|
+
capped_t_can = min(t_can, t_tgt)
|
|
264
|
+
~~~
|
|
265
|
+
|
|
266
|
+
完成条件:
|
|
267
|
+
|
|
268
|
+
~~~
|
|
269
|
+
infra_ok == true
|
|
270
|
+
且 t_can >= t_tgt
|
|
271
|
+
~~~
|
|
272
|
+
|
|
273
|
+
## 10. 提交与测试事件
|
|
274
|
+
|
|
275
|
+
### 提交事件
|
|
276
|
+
|
|
277
|
+
~~~json
|
|
278
|
+
{
|
|
279
|
+
"event": "submit",
|
|
280
|
+
"time": 123.4,
|
|
281
|
+
"submission_id": "s003",
|
|
282
|
+
"source_hash": "sha256:..."
|
|
283
|
+
}
|
|
284
|
+
~~~
|
|
285
|
+
|
|
286
|
+
提交事件不包含分数和测试结果。
|
|
287
|
+
|
|
288
|
+
### 测试请求
|
|
289
|
+
|
|
290
|
+
~~~json
|
|
291
|
+
{
|
|
292
|
+
"event": "test",
|
|
293
|
+
"time": 135.0,
|
|
294
|
+
"submission_id": "s003"
|
|
295
|
+
}
|
|
296
|
+
~~~
|
|
297
|
+
|
|
298
|
+
- 测试使用请求时刻的最新提交快照
|
|
299
|
+
- 测试期间的新提交不影响本次测试
|
|
300
|
+
- 同时只允许一个测试
|
|
301
|
+
- 测试进行中再次请求:stage = busy,score = -1
|
|
302
|
+
|
|
303
|
+
### 测试阶段枚举
|
|
304
|
+
|
|
305
|
+
~~~
|
|
306
|
+
no_submission 没有提交
|
|
307
|
+
compile 编译失败/超时
|
|
308
|
+
infra 基础设施测试失败
|
|
309
|
+
controller 控制器接口/崩溃/超时/非法输出
|
|
310
|
+
simulation 仿真异常/NaN/仿真超时
|
|
311
|
+
scoring 正常测试但 t_can < t_tgt
|
|
312
|
+
completed t_can >= t_tgt,任务完成
|
|
313
|
+
busy 已有测试正在进行
|
|
314
|
+
~~~
|
|
315
|
+
|
|
316
|
+
### 返回给 agent 的测试结果
|
|
317
|
+
|
|
318
|
+
~~~json
|
|
319
|
+
{
|
|
320
|
+
"ok": true,
|
|
321
|
+
"stage": "scoring",
|
|
322
|
+
"t_can": 4.2,
|
|
323
|
+
"completed": false,
|
|
324
|
+
"error": ""
|
|
325
|
+
}
|
|
326
|
+
~~~
|
|
327
|
+
|
|
328
|
+
返回 stage、t_can、completed,不返回最终分数。
|
|
329
|
+
|
|
330
|
+
## 11. 计分
|
|
331
|
+
|
|
332
|
+
从任务开始时刻计时。
|
|
333
|
+
|
|
334
|
+
### 11.1 单时刻分数
|
|
335
|
+
|
|
336
|
+
无效/失败/无提交:
|
|
337
|
+
|
|
338
|
+
~~~
|
|
339
|
+
score = -1
|
|
340
|
+
~~~
|
|
341
|
+
|
|
342
|
+
有效测试:
|
|
343
|
+
|
|
344
|
+
~~~
|
|
345
|
+
score = (min(t_can, t_tgt) - t_tgt) / t_tgt
|
|
346
|
+
~~~
|
|
347
|
+
|
|
348
|
+
范围:
|
|
349
|
+
|
|
350
|
+
~~~
|
|
351
|
+
[-1, 0]
|
|
352
|
+
~~~
|
|
353
|
+
|
|
354
|
+
### 11.2 分数随时间变化
|
|
355
|
+
|
|
356
|
+
- 提交事件不改变 score
|
|
357
|
+
- 只有测试请求改变 score
|
|
358
|
+
- 测试失败:从该测试请求时刻起 score = -1
|
|
359
|
+
- 测试成功:从该测试请求时刻起按 t_can 计分
|
|
360
|
+
- 第一次测试请求之前:score = -1
|
|
361
|
+
- 下一次测试请求之前,score 保持不变
|
|
362
|
+
|
|
363
|
+
### 11.3 最终分数
|
|
364
|
+
|
|
365
|
+
不除以总时间:
|
|
366
|
+
|
|
367
|
+
~~~
|
|
368
|
+
final = integral_0^T_done score(t) dt
|
|
369
|
+
~~~
|
|
370
|
+
|
|
371
|
+
T_done 是第一次返回 stage = completed 的测试请求时间。
|
|
372
|
+
|
|
373
|
+
未完成任务不参与最终排名;手动停止由外部处理。
|
|
374
|
+
|
|
375
|
+
## 12. 完成与终止
|
|
376
|
+
|
|
377
|
+
测试返回:
|
|
378
|
+
|
|
379
|
+
~~~
|
|
380
|
+
stage = completed
|
|
381
|
+
t_can >= t_tgt
|
|
382
|
+
infra_ok = true
|
|
383
|
+
~~~
|
|
384
|
+
|
|
385
|
+
则:
|
|
386
|
+
|
|
387
|
+
- T_done = 该测试请求时间
|
|
388
|
+
- 任务立即结束
|
|
389
|
+
- 测试结果提示:
|
|
390
|
+
|
|
391
|
+
~~~
|
|
392
|
+
任务完成,请立即停止修改并总结实现。
|
|
393
|
+
~~~
|
|
394
|
+
|
|
395
|
+
- 之后的提交和测试请求全部拒绝
|
|
396
|
+
- 不产生新的提交/测试事件
|
|
397
|
+
- 最终分数固定在 T_done 前
|
|
398
|
+
|
|
399
|
+
## 13. 异常处理
|
|
400
|
+
|
|
401
|
+
以下情况均返回 score = -1 并进入对应阶段:
|
|
402
|
+
|
|
403
|
+
- 无提交
|
|
404
|
+
- 源码缺失
|
|
405
|
+
- 编译失败/超时
|
|
406
|
+
- 基础设施测试失败
|
|
407
|
+
- 控制器加载/接口/崩溃/超时/非法输出
|
|
408
|
+
- 仿真 NaN/异常/超时
|
|
409
|
+
- 测试请求 busy
|
|
410
|
+
- 测试请求本身失败
|
|
411
|
+
|
|
412
|
+
异常只影响当前测试请求之后的区间,直到下一次成功测试。
|
|
413
|
+
|
|
414
|
+
## 14. 事件记录
|
|
415
|
+
|
|
416
|
+
插件记录所有提交和测试事件,至少包含:
|
|
417
|
+
|
|
418
|
+
~~~
|
|
419
|
+
event
|
|
420
|
+
time
|
|
421
|
+
submission_id
|
|
422
|
+
source_hash
|
|
423
|
+
stage
|
|
424
|
+
ok
|
|
425
|
+
infra_ok
|
|
426
|
+
t_can
|
|
427
|
+
score
|
|
428
|
+
completed
|
|
429
|
+
~~~
|
|
430
|
+
|
|
431
|
+
提交事件不含 score/result。测试事件含 score 和结果。
|
|
432
|
+
|
|
433
|
+
插件不画图;曲线由外部根据事件记录绘制。
|
|
434
|
+
|
|
435
|
+
## 15. 编译与依赖
|
|
436
|
+
|
|
437
|
+
evaluator 在干净目录构建源码:
|
|
438
|
+
|
|
439
|
+
~~~
|
|
440
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
|
441
|
+
cmake --build build -j4
|
|
442
|
+
~~~
|
|
443
|
+
|
|
444
|
+
规则:
|
|
445
|
+
|
|
446
|
+
- 仅允许 C++17 + CMake + C++ 标准库
|
|
447
|
+
- 无网络
|
|
448
|
+
- 无 torch
|
|
449
|
+
- 无 Python 运行时
|
|
450
|
+
- 源码中出现 torch/Python 依赖:测试失败或赛后人工审核无效
|
|
451
|
+
- 编译失败:stage = compile,score = -1
|
|
452
|
+
|
|
453
|
+
## 16. 赛后人工审核
|
|
454
|
+
|
|
455
|
+
插件只记录和计分。赛后人工审核:
|
|
456
|
+
|
|
457
|
+
- 控制器是否为神经网络
|
|
458
|
+
- 是否实际调用提交的神经网络基础设施
|
|
459
|
+
- 是否存在手写控制律、查表、固定轨迹、外部依赖
|
|
460
|
+
- 源码中是否出现 torch/Python
|
|
461
|
+
|
|
462
|
+
审核不通过:成绩无效。
|
|
463
|
+
|
|
464
|
+
## 17. 排名接口
|
|
465
|
+
|
|
466
|
+
插件只负责产生可比较的最终积分和事件记录。
|
|
467
|
+
|
|
468
|
+
最终积分不除以总时间;未完成任务不参与排名。
|
|
469
|
+
|
|
470
|
+
排名、人工审核和提交有效性由外部处理。
|