evolutionary-policy-optimization 0.4.0__tar.gz → 0.4.2__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.4.0 → evolutionary_policy_optimization-0.4.2}/.gitignore +12 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/PKG-INFO +3 -2
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/epo.py +46 -34
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/pyproject.toml +3 -2
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/LICENSE +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/README.md +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/__init__.py +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/distributed.py +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/env_wrappers.py +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/experimental.py +0 -0
- {evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/evolutionary_policy_optimization/mock_env.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: evolutionary-policy-optimization
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
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
|
|
@@ -40,10 +40,11 @@ Requires-Dist: einops>=0.8.1
|
|
|
40
40
|
Requires-Dist: einx>=0.3.0
|
|
41
41
|
Requires-Dist: ema-pytorch>=0.7.7
|
|
42
42
|
Requires-Dist: hl-gauss-pytorch>=0.2.8
|
|
43
|
-
Requires-Dist: mean-conc-beta>=0.
|
|
43
|
+
Requires-Dist: mean-conc-beta>=0.2.7
|
|
44
44
|
Requires-Dist: torch>=2.2
|
|
45
45
|
Requires-Dist: tqdm
|
|
46
46
|
Requires-Dist: x-mlps-pytorch>=0.3.0
|
|
47
|
+
Requires-Dist: x-ppo>=0.0.16
|
|
47
48
|
Provides-Extra: examples
|
|
48
49
|
Requires-Dist: fire; extra == 'examples'
|
|
49
50
|
Requires-Dist: gymnasium[box2d]>=1.0.0; extra == 'examples'
|
|
@@ -29,6 +29,7 @@ from torch.utils._pytree import tree_map
|
|
|
29
29
|
from torch.utils.data import DataLoader, TensorDataset
|
|
30
30
|
from tqdm import tqdm
|
|
31
31
|
from x_mlps_pytorch import AttnResidualNormedMLP
|
|
32
|
+
from x_ppo import hpo_actor_loss, ppo_actor_loss, spo_actor_loss
|
|
32
33
|
|
|
33
34
|
from evolutionary_policy_optimization.distributed import all_gather, get_world_and_rank, is_distributed, maybe_barrier, maybe_sync_seed
|
|
34
35
|
|
|
@@ -52,6 +53,20 @@ def divisible_by(num, den):
|
|
|
52
53
|
def to_device(inp, device):
|
|
53
54
|
return tree_map(lambda t: t.to(device) if is_tensor(t) else t, inp)
|
|
54
55
|
|
|
56
|
+
class ShuffledBatches:
|
|
57
|
+
# fresh permutation on every pass
|
|
58
|
+
|
|
59
|
+
def __init__(self, fields, batch_size):
|
|
60
|
+
self.fields = fields
|
|
61
|
+
self.batch_size = batch_size
|
|
62
|
+
|
|
63
|
+
def __iter__(self):
|
|
64
|
+
perm = torch.randperm(self.fields[0].shape[0])
|
|
65
|
+
|
|
66
|
+
for i in range(0, len(perm), self.batch_size):
|
|
67
|
+
b = perm[i:i + self.batch_size]
|
|
68
|
+
yield [field[b] for field in self.fields]
|
|
69
|
+
|
|
55
70
|
def maybe(fn):
|
|
56
71
|
|
|
57
72
|
@wraps(fn)
|
|
@@ -1234,6 +1249,7 @@ class Agent(Module):
|
|
|
1234
1249
|
hidden_spr_ema_update = 0.99,
|
|
1235
1250
|
get_fitness_scores: Callable[..., Tensor] = get_fitness_scores,
|
|
1236
1251
|
wrap_with_accelerate: bool = True,
|
|
1252
|
+
use_dataloader = False,
|
|
1237
1253
|
accelerate_kwargs: dict = dict(),
|
|
1238
1254
|
accelerator = None,
|
|
1239
1255
|
quiet: bool = False,
|
|
@@ -1245,6 +1261,7 @@ class Agent(Module):
|
|
|
1245
1261
|
# hf accelerate
|
|
1246
1262
|
|
|
1247
1263
|
self.wrap_with_accelerate = wrap_with_accelerate
|
|
1264
|
+
self.use_dataloader = use_dataloader
|
|
1248
1265
|
|
|
1249
1266
|
if wrap_with_accelerate:
|
|
1250
1267
|
self.accelerate = accelerator if exists(accelerator) else Accelerator(**accelerate_kwargs)
|
|
@@ -1592,13 +1609,12 @@ class Agent(Module):
|
|
|
1592
1609
|
epochs = 2
|
|
1593
1610
|
|
|
1594
1611
|
):
|
|
1595
|
-
memories_and_cumulative_rewards = to_device(memories_and_cumulative_rewards, self.device)
|
|
1596
|
-
|
|
1597
1612
|
memories_list, rewards_per_latent_episode = memories_and_cumulative_rewards
|
|
1598
1613
|
|
|
1599
|
-
# stack
|
|
1614
|
+
# stack, then move once per field
|
|
1600
1615
|
|
|
1601
|
-
memories = map(stack, zip(*memories_list))
|
|
1616
|
+
memories = [t.to(self.device) for t in map(stack, zip(*memories_list))]
|
|
1617
|
+
rewards_per_latent_episode = rewards_per_latent_episode.to(self.device)
|
|
1602
1618
|
|
|
1603
1619
|
memories_list.clear()
|
|
1604
1620
|
|
|
@@ -1640,12 +1656,15 @@ class Agent(Module):
|
|
|
1640
1656
|
|
|
1641
1657
|
valid_episode = episode_ids >= 0
|
|
1642
1658
|
|
|
1643
|
-
|
|
1659
|
+
fields = tuple(t[valid_episode] for t in (advantages, states, next_states, latent_gene_ids, actions, log_probs, values, dones))
|
|
1644
1660
|
|
|
1645
|
-
|
|
1661
|
+
if self.wrap_with_accelerate or self.use_dataloader:
|
|
1662
|
+
dataloader = DataLoader(TensorDataset(*fields), batch_size = self.batch_size, shuffle = True)
|
|
1646
1663
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1664
|
+
if self.wrap_with_accelerate:
|
|
1665
|
+
dataloader = self.accelerate.prepare(dataloader)
|
|
1666
|
+
else:
|
|
1667
|
+
dataloader = ShuffledBatches(fields, self.batch_size)
|
|
1649
1668
|
|
|
1650
1669
|
# updating actor and critic
|
|
1651
1670
|
|
|
@@ -1845,39 +1864,31 @@ def actor_loss(
|
|
|
1845
1864
|
advantages, # Float[b]
|
|
1846
1865
|
eps_clip = 0.2,
|
|
1847
1866
|
entropy_weight = .01,
|
|
1848
|
-
eps = 1e-5,
|
|
1849
1867
|
norm_advantages = True,
|
|
1850
|
-
use_spo = False
|
|
1868
|
+
use_spo = False,
|
|
1869
|
+
use_hpo = False
|
|
1851
1870
|
):
|
|
1852
|
-
batch = advantages.shape[0]
|
|
1853
|
-
|
|
1854
1871
|
log_probs = sum_to_batch(distr.log_prob(actions))
|
|
1855
1872
|
entropy = sum_to_batch(distr.entropy())
|
|
1856
1873
|
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
if use_spo:
|
|
1863
|
-
# simple policy optimization - line 14 Algorithm 1 https://arxiv.org/abs/2401.16025v9
|
|
1864
|
-
|
|
1865
|
-
actor_loss = - (
|
|
1866
|
-
ratio * advantages -
|
|
1867
|
-
advantages.abs() / (2 * eps_clip) * (ratio - 1.).square()
|
|
1868
|
-
)
|
|
1874
|
+
if use_hpo:
|
|
1875
|
+
loss_fn = hpo_actor_loss
|
|
1876
|
+
elif use_spo:
|
|
1877
|
+
loss_fn = spo_actor_loss
|
|
1869
1878
|
else:
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1879
|
+
loss_fn = ppo_actor_loss
|
|
1880
|
+
|
|
1881
|
+
loss = loss_fn(
|
|
1882
|
+
log_probs,
|
|
1883
|
+
old_log_probs,
|
|
1884
|
+
advantages,
|
|
1885
|
+
eps_clip = eps_clip,
|
|
1886
|
+
normalize_advantages = norm_advantages,
|
|
1887
|
+
)
|
|
1877
1888
|
|
|
1878
|
-
|
|
1889
|
+
# entropy bonus
|
|
1879
1890
|
|
|
1880
|
-
return (
|
|
1891
|
+
return (loss - entropy_weight * entropy).mean()
|
|
1881
1892
|
|
|
1882
1893
|
# agent contains the actor, critic, and the latent genetic pool
|
|
1883
1894
|
|
|
@@ -2160,6 +2171,7 @@ class EPO(Module):
|
|
|
2160
2171
|
|
|
2161
2172
|
next_obs, rewards, terminated, truncated = env.step_batch(actions.cpu().numpy(), worker_ids = active)[:4]
|
|
2162
2173
|
|
|
2174
|
+
next_states = from_numpy(np.ascontiguousarray(next_obs)).float().to(self.device)
|
|
2163
2175
|
rewards = from_numpy(np.asarray(rewards)).float().to(self.device)
|
|
2164
2176
|
terminated = from_numpy(np.asarray(terminated)).to(self.device)
|
|
2165
2177
|
truncated = from_numpy(np.asarray(truncated)).to(self.device)
|
|
@@ -2169,7 +2181,7 @@ class EPO(Module):
|
|
|
2169
2181
|
|
|
2170
2182
|
latent_id, episode_id, latent, state = slot.latent_id, slot.episode_id, slot.latent, slot.state
|
|
2171
2183
|
|
|
2172
|
-
next_state =
|
|
2184
|
+
next_state = next_states[k]
|
|
2173
2185
|
|
|
2174
2186
|
reward, terminated_at, truncated_at = rewards[k], terminated[k], truncated[k]
|
|
2175
2187
|
|
{evolutionary_policy_optimization-0.4.0 → evolutionary_policy_optimization-0.4.2}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "evolutionary-policy-optimization"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.2"
|
|
4
4
|
description = "EPO - Pytorch"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Phil Wang", email = "lucidrains@gmail.com" }
|
|
@@ -30,10 +30,11 @@ dependencies = [
|
|
|
30
30
|
'einops>=0.8.1',
|
|
31
31
|
'ema-pytorch>=0.7.7',
|
|
32
32
|
'hl-gauss-pytorch>=0.2.8',
|
|
33
|
-
'mean-conc-beta>=0.
|
|
33
|
+
'mean-conc-beta>=0.2.7',
|
|
34
34
|
'torch>=2.2',
|
|
35
35
|
'tqdm',
|
|
36
36
|
"x-mlps-pytorch>=0.3.0",
|
|
37
|
+
"x-ppo>=0.0.16",
|
|
37
38
|
]
|
|
38
39
|
|
|
39
40
|
[project.urls]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|