Detecting Silent Faults at the Environment-Trainer Boundary in Reinforcement Learning
Organizations: Tsinghua University, Beijing, China
Abstract
Robot reinforcement learning increasingly runs environments outside the trainer: in another process, on another machine, in another language. Many faults at this boundary raise no error. We make the boundary a wire protocol and ask what notices a fault in it. On Pendulum, HalfCheetah, Hopper and a 7-joint arm (Pusher), we injected up to 23 faults into what crosses the wire and 2 into the trainer's log, from one value to every value. Unless every value was wrong, a learning-curve threshold caught at most one run in ten, and a comparison with ten fault-free seeds at most 21%. A clean evaluation of all 1,060 final policies agreed with the curves: of the 728 boundary-fault runs both curve checks passed, 723 scored no more than three standard deviations below fault-free seeds, though nearly all ended on other weights and, for reward faults, logged other returns. Checks of the run itself, not of its outcome, saw every fault. A step ledger kept on both sides and compared step by step caught and located every fault that crossed, on Pendulum, Hopper and Pusher on one machine and on Pendulum across two, with no fault-free run and, on Pendulum, a median 3% more training time. An episode record kept at the environment caught the faults in the trainer's log. We list such faults found in practice, in Gymnasium 1.3 and our own code and, reported by others, in five multi-agent libraries, and recommend a step ledger and episode counts kept at the environment.
Figures & tables
| kind | where | what was wrong |
|---|---|---|
| reward | RLlib [ 15 ] | an agent with no last observation got reward 0, not the environment’s |
| Tianshou 0.4.2 [ 16 ] | rewards earned while the opponent moved were dropped | |
| action | PettingZoo 1.22 [ 17 ] | one-dimensional continuous actions were cast to integers |
| final obs. | SuperSuit [ 18 ] | the reset’s info overwrote the terminal observation |
| episode end | MAPPO’s SMACv2 wrapper [ 19 ] | dead agents’ padded steps were trained on as real |
| log | Gymnasium 1.3 (E51) | under SAME_STEP , every episode after an env’s first lost its first reward and a step (fixed in 1.4 [ 20 ] ) |
Appendix figures & tables8 assets
Supplementary material from the paper’s appendix.
Appendix
| kind | where | what was wrong |
|---|---|---|
| lifecycle | RLinf (E48) | environments never closed; outside clients reconnected 3,190 times in 25 minutes |
| our bridge (E48) | a surplus client was told to resync, not stop: 2 million reconnects in 10 minutes | |
| cost | our scheduler (E47) | a 0.1 ms sleep that the event loop rounds to 1 ms made collection 1.87 slower; the fix left the weights byte-identical |
| exp. | trainer | environments ran | result |
| E50 | SB3, PPO | in-process vs. bridge | same weights 6/6 |
| E53 | SB3, CNN | Atari frames, as E50 | same weights 3/3 |
| E52 | SB3, PPO | proxy, 0–25 ms each way | same weights 12/12 |
| E43 | PlugRL, FPO [ 41 ] | same machine | passes 6/6 |
| (HalfCheetah [ 42 ] ) | laptop, Wi-Fi + Tailscale | passes 6/6 | |
| E44 | PlugRL, PPO [ 43 ] | Python env client | passes 3/3 |
| system | trains | packages | size | torch |
|---|---|---|---|---|
| PlugRL, C++ client | yes | 0 | 86 KB | no |
| PlugRL, minimal Python | yes | 2 | 2.6 MB | no |
| PlugRL, full env client | yes | 31 | 222 MB | no |
| RLlib external env [ 3 ] | yes | 64 | 6.1 GB | CUDA |
| LeRobot HIL-SERL [ 7 ] | yes | 144 | 6.1 GB | CUDA |
| dm_env_rpc [ 38 ] | no trainer | 12 | 81 MB | no |
| env | seed | weights (SHA-256) | in-process | bridge | per vector step |
|---|---|---|---|---|---|
| Pendulum | 0 | ec5b8226 both | 12.7 s | 16.3 s | +0.57 ms |
| 1 | 062e92e3 both | 12.7 s | 16.5 s | +0.58 ms | |
| 2 | 3a8d968f both | 12.7 s | 16.5 s | +0.58 ms | |
| HalfCheetah | 0 | 8261c03a both | 64.0 s | 76.0 s | +0.47 ms |
| 1 | 86564694 both | 66.7 s | 76.5 s | +0.38 ms | |
| 2 | 65cc8843 both | 67.0 s | 76.5 s | +0.37 ms |
| counter | autoreset | logged |
|---|---|---|
| Gymnasium vector RecordEpisodeStatistics | NEXT_STEP | |
| the same | SAME_STEP | , then |
| single-env RecordEpisodeStatistics per sub-env | both | |
| CleanRL’s logging loop, verbatim | NEXT_STEP | nothing |
| the same | SAME_STEP | TypeError |
| SB3 VecMonitor ; SB3 Monitor | SB3’s |
Robotic RL
Robotic reinforcement learning uses trial-and-error learning to help robots control, navigate, and manipulate objects.
See all 319 papers