evolutionary-policy-optimization 0.2.18__tar.gz → 0.2.20__tar.gz
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.
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/PKG-INFO +58 -13
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/README.md +52 -11
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/distributed.py +4 -0
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/epo.py +32 -27
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/experimental.py +12 -5
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/pyproject.toml +7 -3
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/.gitignore +0 -0
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/LICENSE +0 -0
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/__init__.py +0 -0
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/env_wrappers.py +0 -0
- {evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/evolutionary_policy_optimization/mock_env.py +0 -0
{evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: evolutionary-policy-optimization
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.20
|
|
4
4
|
Summary: EPO - Pytorch
|
|
5
5
|
Project-URL: Homepage, https://pypi.org/project/evolutionary-policy-optimization/
|
|
6
6
|
Project-URL: Repository, https://github.com/lucidrains/evolutionary-policy-optimization
|
|
@@ -45,9 +45,13 @@ Requires-Dist: torch>=2.2
|
|
|
45
45
|
Requires-Dist: tqdm
|
|
46
46
|
Requires-Dist: x-mlps-pytorch>=0.3.0
|
|
47
47
|
Provides-Extra: examples
|
|
48
|
+
Requires-Dist: fire; extra == 'examples'
|
|
49
|
+
Requires-Dist: gymnasium[box2d]>=1.0.0; extra == 'examples'
|
|
50
|
+
Requires-Dist: moviepy; extra == 'examples'
|
|
48
51
|
Requires-Dist: numpy; extra == 'examples'
|
|
49
|
-
Requires-Dist:
|
|
52
|
+
Requires-Dist: swig; extra == 'examples'
|
|
50
53
|
Requires-Dist: tqdm; extra == 'examples'
|
|
54
|
+
Requires-Dist: wandb; extra == 'examples'
|
|
51
55
|
Provides-Extra: experimental
|
|
52
56
|
Requires-Dist: tensordict; extra == 'experimental'
|
|
53
57
|
Requires-Dist: torchvision; extra == 'experimental'
|
|
@@ -149,6 +153,34 @@ agent.save('./agent.pt', overwrite = True)
|
|
|
149
153
|
agent.load('./agent.pt')
|
|
150
154
|
```
|
|
151
155
|
|
|
156
|
+
## Train Gym
|
|
157
|
+
|
|
158
|
+
An example training script for LunarLander-v3 is provided at `train_gym.py`
|
|
159
|
+
|
|
160
|
+
First install example dependencies
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
$ pip install '.[examples]' # or `uv pip install '.[examples]'`
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Single process
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
$ python train_gym.py --cpu
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Distributed with 8 processes (one latent per process)
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
$ torchrun --nproc_per_node=8 train_gym.py --cpu
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
With wandb logging
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
$ torchrun --nproc_per_node=8 train_gym.py --cpu --use_wandb
|
|
182
|
+
```
|
|
183
|
+
|
|
152
184
|
## Contributing
|
|
153
185
|
|
|
154
186
|
At the project root, run
|
|
@@ -323,6 +355,30 @@ That's it
|
|
|
323
355
|
}
|
|
324
356
|
```
|
|
325
357
|
|
|
358
|
+
```bibtex
|
|
359
|
+
@article{Eysenbach2018DiversityIA,
|
|
360
|
+
title = {Diversity is All You Need: Learning Skills without a Reward Function},
|
|
361
|
+
author = {Benjamin Eysenbach and Abhishek Gupta and Julian Ibarz and Sergey Levine},
|
|
362
|
+
journal = {ArXiv},
|
|
363
|
+
year = {2018},
|
|
364
|
+
volume = {abs/1802.06070},
|
|
365
|
+
url = {https://arxiv.org/abs/1802.06070}
|
|
366
|
+
url = {https://arxiv.org/abs/2602.16863},
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
```bibtex
|
|
370
|
+
@article{Zhu2025Hybrid,
|
|
371
|
+
author = {Zhu, Zimo and Yu, Chuanqiang and Wang, Junti},
|
|
372
|
+
title = {A Hybrid Genetic Algorithm and Proximal Policy Optimization System for Efficient Multi-Agent Task Allocation},
|
|
373
|
+
journal = {Systems},
|
|
374
|
+
volume = {13},
|
|
375
|
+
year = {2025},
|
|
376
|
+
number = {6},
|
|
377
|
+
article-number = {453},
|
|
378
|
+
url = {https://www.mdpi.com/2079-8954/13/6/453},
|
|
379
|
+
issn = {2079-8954}
|
|
380
|
+
```
|
|
381
|
+
|
|
326
382
|
```bibtex
|
|
327
383
|
@misc{kedia2026simtoolrealobjectcentricpolicyzeroshot,
|
|
328
384
|
title = {SimToolReal: An Object-Centric Policy for Zero-Shot Dexterous Tool Manipulation},
|
|
@@ -335,15 +391,4 @@ That's it
|
|
|
335
391
|
}
|
|
336
392
|
```
|
|
337
393
|
|
|
338
|
-
```bibtex
|
|
339
|
-
@article{Eysenbach2018DiversityIA,
|
|
340
|
-
title = {Diversity is All You Need: Learning Skills without a Reward Function},
|
|
341
|
-
author = {Benjamin Eysenbach and Abhishek Gupta and Julian Ibarz and Sergey Levine},
|
|
342
|
-
journal = {ArXiv},
|
|
343
|
-
year = {2018},
|
|
344
|
-
volume = {abs/1802.06070},
|
|
345
|
-
url = {https://arxiv.org/abs/1802.06070}
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
394
|
*Evolution is cleverer than you are.* - Leslie Orgel
|
{evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/README.md
RENAMED
|
@@ -91,6 +91,34 @@ agent.save('./agent.pt', overwrite = True)
|
|
|
91
91
|
agent.load('./agent.pt')
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
## Train Gym
|
|
95
|
+
|
|
96
|
+
An example training script for LunarLander-v3 is provided at `train_gym.py`
|
|
97
|
+
|
|
98
|
+
First install example dependencies
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
$ pip install '.[examples]' # or `uv pip install '.[examples]'`
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Single process
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
$ python train_gym.py --cpu
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Distributed with 8 processes (one latent per process)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
$ torchrun --nproc_per_node=8 train_gym.py --cpu
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
With wandb logging
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
$ torchrun --nproc_per_node=8 train_gym.py --cpu --use_wandb
|
|
120
|
+
```
|
|
121
|
+
|
|
94
122
|
## Contributing
|
|
95
123
|
|
|
96
124
|
At the project root, run
|
|
@@ -265,6 +293,30 @@ That's it
|
|
|
265
293
|
}
|
|
266
294
|
```
|
|
267
295
|
|
|
296
|
+
```bibtex
|
|
297
|
+
@article{Eysenbach2018DiversityIA,
|
|
298
|
+
title = {Diversity is All You Need: Learning Skills without a Reward Function},
|
|
299
|
+
author = {Benjamin Eysenbach and Abhishek Gupta and Julian Ibarz and Sergey Levine},
|
|
300
|
+
journal = {ArXiv},
|
|
301
|
+
year = {2018},
|
|
302
|
+
volume = {abs/1802.06070},
|
|
303
|
+
url = {https://arxiv.org/abs/1802.06070}
|
|
304
|
+
url = {https://arxiv.org/abs/2602.16863},
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
```bibtex
|
|
308
|
+
@article{Zhu2025Hybrid,
|
|
309
|
+
author = {Zhu, Zimo and Yu, Chuanqiang and Wang, Junti},
|
|
310
|
+
title = {A Hybrid Genetic Algorithm and Proximal Policy Optimization System for Efficient Multi-Agent Task Allocation},
|
|
311
|
+
journal = {Systems},
|
|
312
|
+
volume = {13},
|
|
313
|
+
year = {2025},
|
|
314
|
+
number = {6},
|
|
315
|
+
article-number = {453},
|
|
316
|
+
url = {https://www.mdpi.com/2079-8954/13/6/453},
|
|
317
|
+
issn = {2079-8954}
|
|
318
|
+
```
|
|
319
|
+
|
|
268
320
|
```bibtex
|
|
269
321
|
@misc{kedia2026simtoolrealobjectcentricpolicyzeroshot,
|
|
270
322
|
title = {SimToolReal: An Object-Centric Policy for Zero-Shot Dexterous Tool Manipulation},
|
|
@@ -277,15 +329,4 @@ That's it
|
|
|
277
329
|
}
|
|
278
330
|
```
|
|
279
331
|
|
|
280
|
-
```bibtex
|
|
281
|
-
@article{Eysenbach2018DiversityIA,
|
|
282
|
-
title = {Diversity is All You Need: Learning Skills without a Reward Function},
|
|
283
|
-
author = {Benjamin Eysenbach and Abhishek Gupta and Julian Ibarz and Sergey Levine},
|
|
284
|
-
journal = {ArXiv},
|
|
285
|
-
year = {2018},
|
|
286
|
-
volume = {abs/1802.06070},
|
|
287
|
-
url = {https://arxiv.org/abs/1802.06070}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
332
|
*Evolution is cleverer than you are.* - Leslie Orgel
|
|
@@ -86,3 +86,7 @@ def all_gather_variable_dim(t, dim = 0, sizes = None):
|
|
|
86
86
|
gathered_tensors = gathered_tensors.index_select(dim, indices)
|
|
87
87
|
|
|
88
88
|
return gathered_tensors, sizes
|
|
89
|
+
|
|
90
|
+
def all_gather(t, dim = 0):
|
|
91
|
+
gathered, _ = all_gather_variable_dim(t, dim = dim)
|
|
92
|
+
return gathered
|
|
@@ -28,7 +28,7 @@ from evolutionary_policy_optimization.distributed import (
|
|
|
28
28
|
is_distributed,
|
|
29
29
|
get_world_and_rank,
|
|
30
30
|
maybe_sync_seed,
|
|
31
|
-
|
|
31
|
+
all_gather,
|
|
32
32
|
maybe_barrier
|
|
33
33
|
)
|
|
34
34
|
|
|
@@ -1121,6 +1121,7 @@ class Agent(Module):
|
|
|
1121
1121
|
get_fitness_scores: Callable[..., Tensor] = get_fitness_scores,
|
|
1122
1122
|
wrap_with_accelerate: bool = True,
|
|
1123
1123
|
accelerate_kwargs: dict = dict(),
|
|
1124
|
+
accelerator = None,
|
|
1124
1125
|
):
|
|
1125
1126
|
super().__init__()
|
|
1126
1127
|
|
|
@@ -1129,8 +1130,7 @@ class Agent(Module):
|
|
|
1129
1130
|
self.wrap_with_accelerate = wrap_with_accelerate
|
|
1130
1131
|
|
|
1131
1132
|
if wrap_with_accelerate:
|
|
1132
|
-
accelerate = Accelerator(**accelerate_kwargs)
|
|
1133
|
-
self.accelerate = accelerate
|
|
1133
|
+
self.accelerate = accelerator if exists(accelerator) else Accelerator(**accelerate_kwargs)
|
|
1134
1134
|
|
|
1135
1135
|
# state norm
|
|
1136
1136
|
|
|
@@ -1239,35 +1239,40 @@ class Agent(Module):
|
|
|
1239
1239
|
|
|
1240
1240
|
if wrap_with_accelerate:
|
|
1241
1241
|
self.clip_grad_norm_ = self.accelerate.clip_grad_norm_
|
|
1242
|
+
device = self.accelerate.device
|
|
1243
|
+
|
|
1244
|
+
# device placement for modules without gradient parameters
|
|
1245
|
+
|
|
1246
|
+
for m in (self.state_norm, self.latent_gene_pool):
|
|
1247
|
+
if exists(m):
|
|
1248
|
+
m.to(device)
|
|
1249
|
+
|
|
1250
|
+
# DDP wrap models with gradient parameters + prepare optimizers
|
|
1242
1251
|
|
|
1243
1252
|
(
|
|
1244
|
-
self.state_norm,
|
|
1245
1253
|
self.actor,
|
|
1246
1254
|
self.critic,
|
|
1247
|
-
self.latent_gene_pool,
|
|
1248
|
-
self.diversity_discr,
|
|
1249
1255
|
self.actor_optim,
|
|
1250
1256
|
self.critic_optim,
|
|
1251
|
-
|
|
1252
|
-
self.
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
self.actor,
|
|
1257
|
-
self.critic,
|
|
1258
|
-
self.latent_gene_pool,
|
|
1259
|
-
self.diversity_discr,
|
|
1260
|
-
self.actor_optim,
|
|
1261
|
-
self.critic_optim,
|
|
1262
|
-
self.latent_optim,
|
|
1263
|
-
self.diversity_discr_optim,
|
|
1264
|
-
)
|
|
1257
|
+
) = self.accelerate.prepare(
|
|
1258
|
+
self.actor,
|
|
1259
|
+
self.critic,
|
|
1260
|
+
self.actor_optim,
|
|
1261
|
+
self.critic_optim,
|
|
1265
1262
|
)
|
|
1266
1263
|
|
|
1264
|
+
if exists(self.diversity_discr):
|
|
1265
|
+
self.diversity_discr, self.diversity_discr_optim = self.accelerate.prepare(
|
|
1266
|
+
self.diversity_discr, self.diversity_discr_optim
|
|
1267
|
+
)
|
|
1268
|
+
|
|
1269
|
+
if exists(self.latent_optim):
|
|
1270
|
+
self.latent_optim = self.accelerate.prepare(self.latent_optim)
|
|
1271
|
+
|
|
1267
1272
|
if exists(self.critic_ema):
|
|
1268
|
-
self.critic_ema.to(
|
|
1273
|
+
self.critic_ema.to(device)
|
|
1269
1274
|
|
|
1270
|
-
step = step.to(
|
|
1275
|
+
step = step.to(device)
|
|
1271
1276
|
|
|
1272
1277
|
# device tracking
|
|
1273
1278
|
|
|
@@ -1418,9 +1423,8 @@ class Agent(Module):
|
|
|
1418
1423
|
maybe_barrier()
|
|
1419
1424
|
|
|
1420
1425
|
if is_distributed():
|
|
1421
|
-
memories =
|
|
1422
|
-
|
|
1423
|
-
rewards_per_latent_episode = dist.all_reduce(rewards_per_latent_episode)
|
|
1426
|
+
memories = [all_gather(m) for m in memories]
|
|
1427
|
+
dist.all_reduce(rewards_per_latent_episode)
|
|
1424
1428
|
|
|
1425
1429
|
# calculate fitness scores
|
|
1426
1430
|
|
|
@@ -1500,7 +1504,7 @@ class Agent(Module):
|
|
|
1500
1504
|
|
|
1501
1505
|
# learn critic with maybe classification loss
|
|
1502
1506
|
|
|
1503
|
-
critic_loss = self.critic.forward_for_loss(
|
|
1507
|
+
critic_loss = self.unwrap_model(self.critic).forward_for_loss(
|
|
1504
1508
|
states,
|
|
1505
1509
|
latents,
|
|
1506
1510
|
old_values = old_values,
|
|
@@ -1668,6 +1672,7 @@ def create_agent(
|
|
|
1668
1672
|
critic_dim,
|
|
1669
1673
|
critic_mlp_depth,
|
|
1670
1674
|
use_critic_ema = True,
|
|
1675
|
+
use_state_norm = False,
|
|
1671
1676
|
latent_gene_pool_kwargs: dict = dict(),
|
|
1672
1677
|
actor_kwargs: dict = dict(),
|
|
1673
1678
|
critic_kwargs: dict = dict(),
|
|
@@ -1685,7 +1690,7 @@ def create_agent(
|
|
|
1685
1690
|
**latent_gene_pool_kwargs
|
|
1686
1691
|
) if has_latent_genes else None
|
|
1687
1692
|
|
|
1688
|
-
state_norm = StateNorm(dim = dim_state)
|
|
1693
|
+
state_norm = StateNorm(dim = dim_state) if use_state_norm else None
|
|
1689
1694
|
|
|
1690
1695
|
actor = Actor(
|
|
1691
1696
|
num_actions = actor_num_actions,
|
|
@@ -7,6 +7,7 @@ import torch.nn.functional as F
|
|
|
7
7
|
from torch.func import vmap, functional_call
|
|
8
8
|
from torch.nn import Module, ParameterList
|
|
9
9
|
|
|
10
|
+
import einx
|
|
10
11
|
from einops import rearrange, reduce, repeat
|
|
11
12
|
|
|
12
13
|
def exists(v):
|
|
@@ -31,11 +32,12 @@ def shrink_and_perturb_(
|
|
|
31
32
|
|
|
32
33
|
def crossover_weights(
|
|
33
34
|
w1, w2,
|
|
35
|
+
alpha = 0.5,
|
|
34
36
|
shrink_perturb = False,
|
|
35
37
|
shrink_factor = 0.4,
|
|
36
38
|
perturb_factor = 0.1
|
|
37
39
|
):
|
|
38
|
-
assert
|
|
40
|
+
assert w1.shape == w2.shape
|
|
39
41
|
|
|
40
42
|
no_batch = w1.ndim == 2
|
|
41
43
|
|
|
@@ -58,12 +60,17 @@ def crossover_weights(
|
|
|
58
60
|
u1, s1, v1 = torch.svd(w1)
|
|
59
61
|
u2, s2, v2 = torch.svd(w2)
|
|
60
62
|
|
|
63
|
+
sign = einx.dot('b j d, b j d -> b d', v1, v2).sign()
|
|
64
|
+
|
|
65
|
+
u2 = einx.multiply('b i d, b d -> b i d', u2, sign)
|
|
66
|
+
v2 = einx.multiply('b j d, b d -> b j d', v2, sign)
|
|
67
|
+
|
|
61
68
|
batch_randperm = torch.randn((batch, rank), device = w1.device).argsort(dim = -1)
|
|
62
|
-
mask = batch_randperm < (rank
|
|
69
|
+
mask = batch_randperm < int(rank * alpha)
|
|
63
70
|
|
|
64
|
-
u =
|
|
65
|
-
s =
|
|
66
|
-
v =
|
|
71
|
+
u = einx.where('b d, b i d, b i d -> b i d', mask, u1, u2)
|
|
72
|
+
s = einx.where('b d, b d, b d -> b d', mask, s1, s2)
|
|
73
|
+
v = einx.where('b d, b j d, b j d -> b j d', mask, v1, v2)
|
|
67
74
|
|
|
68
75
|
out = u @ torch.diag_embed(s) @ v.mT
|
|
69
76
|
|
{evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "evolutionary-policy-optimization"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.20"
|
|
4
4
|
description = "EPO - Pytorch"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Phil Wang", email = "lucidrains@gmail.com" }
|
|
@@ -14,7 +14,7 @@ keywords = [
|
|
|
14
14
|
'reinforcement learning',
|
|
15
15
|
'genetic algorithms',
|
|
16
16
|
'robotics'
|
|
17
|
-
|
|
17
|
+
]
|
|
18
18
|
classifiers = [
|
|
19
19
|
'Development Status :: 4 - Beta',
|
|
20
20
|
'Intended Audience :: Developers',
|
|
@@ -42,9 +42,13 @@ Repository = "https://github.com/lucidrains/evolutionary-policy-optimization"
|
|
|
42
42
|
|
|
43
43
|
[project.optional-dependencies]
|
|
44
44
|
examples = [
|
|
45
|
+
"fire",
|
|
46
|
+
"gymnasium[box2d]>=1.0.0",
|
|
47
|
+
"moviepy",
|
|
45
48
|
"numpy",
|
|
46
|
-
"
|
|
49
|
+
"swig",
|
|
47
50
|
"tqdm",
|
|
51
|
+
"wandb",
|
|
48
52
|
]
|
|
49
53
|
|
|
50
54
|
experimental = [
|
{evolutionary_policy_optimization-0.2.18 → evolutionary_policy_optimization-0.2.20}/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|