Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to gymnasium #72

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,39 @@

**Status**: early beta.

*seals*, the Suite of Environments for Algorithms that Learn Specifications, is a toolkit for
_seals_, the Suite of Environments for Algorithms that Learn Specifications, is a toolkit for
evaluating specification learning algorithms, such as reward or imitation learning. The
environments are compatible with [Gym](https://github.com/openai/gym), but are designed
to test algorithms that learn from user data, without requiring a procedurally specified
reward function.

There are two types of environments in *seals*:
There are two types of environments in _seals_:

- **Diagnostic Tasks** which test individual facets of algorithm performance in isolation.
- **Renovated Environments**, adaptations of widely-used benchmarks such as MuJoCo continuous
control tasks and Atari games to be suitable for specification learning benchmarks. In particular,
we remove any side-channel sources of reward information from MuJoCo tasks, and give Atari games constant-length episodes (although most Atari environments have observations that include the score).
- **Diagnostic Tasks** which test individual facets of algorithm performance in isolation.
- **Renovated Environments**, adaptations of widely-used benchmarks such as MuJoCo continuous
control tasks and Atari games to be suitable for specification learning benchmarks. In particular,
we remove any side-channel sources of reward information from MuJoCo tasks, and give Atari games constant-length episodes (although most Atari environments have observations that include the score).

_seals_ is under active development and we intend to add more categories of tasks soon.

*seals* is under active development and we intend to add more categories of tasks soon.

You may also be interested in our sister project [imitation](https://github.com/humancompatibleai/imitation/),
providing implementations of a variety of imitation and reward learning algorithms.

Check out our [documentation](https://seals.readthedocs.io/en/latest/) for more information about *seals*.
Check out our [documentation](https://seals.readthedocs.io/en/latest/) for more information about _seals_.

# Quickstart

To install the latest release from PyPI, run:

```bash
pip install seals
```

All *seals* environments are available in the Gym registry. Simply import it and then use as you
All _seals_ environments are available in the Gym registry. Simply import it and then use as you
would with your usual RL or specification learning algroithm:

```python
import gym
import gymnasium as gym
import seals

env = gym.make('seals/CartPole-v0')
Expand Down Expand Up @@ -86,7 +86,7 @@ for type checking.
## Workflow

Trivial changes (e.g. typo fixes) may be made directly by maintainers. Any non-trivial changes
must be proposed in a PR and approved by at least one maintainer. PRs must pass the continuous
must be proposed in a PR and approved by at least one maintainer. PRs must pass the continuous
integration tests (CircleCI linting, type checking, unit tests and CodeCov) to be merged.

It is often helpful to open an issue before proposing a PR, to allow for discussion of the design
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ build-backend = "setuptools.build_meta"
target-version = ["py38"]

[[tool.mypy.overrides]]
module = [
"gym.*",
"setuptools_scm.*",
]
module = ["gym.*", "setuptools_scm.*"]
ignore_missing_imports = true

[tool.ruff]
select = ["E", "F"]
8 changes: 2 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ def get_readme() -> str:
"pytest-xdist",
"pytype",
"stable-baselines3>=0.9.0",
# TODO(adam): remove pyglet pin once Gym upgraded to >0.21
# Workaround for https://github.com/openai/gym/issues/2986
# Discussed in https://github.com/HumanCompatibleAI/imitation/pull/603
"pyglet==1.5.27",
"setuptools_scm~=7.0.5",
*ATARI_REQUIRE,
]
Expand All @@ -140,7 +136,7 @@ def get_readme() -> str:
packages=find_packages("src"),
package_dir={"": "src"},
package_data={"seals": ["py.typed"]},
install_requires=["gym", "numpy"],
install_requires=["gymnasium", "numpy"],
tests_require=TESTS_REQUIRE,
extras_require={
# recommended packages for development
Expand All @@ -149,7 +145,7 @@ def get_readme() -> str:
"test": TESTS_REQUIRE,
# We'd like to specify `gym[mujoco]`, but this is a no-op when Gym is already
# installed. See https://github.com/pypa/pip/issues/4957 for issue.
"mujoco": ["mujoco_py>=1.50, <2.0", "imageio"],
"mujoco": ["mujoco", "imageio"],
"atari": ATARI_REQUIRE,
},
url="https://github.com/HumanCompatibleAI/benchmark-environments",
Expand Down
6 changes: 3 additions & 3 deletions src/seals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from importlib import metadata

import gym
import gymnasium as gym

from seals import atari, util
import seals.diagnostics # noqa: F401
from seals import atari, util

try:
__version__ = metadata.version("seals")
Expand Down Expand Up @@ -38,5 +38,5 @@

# Atari

GYM_ATARI_ENV_SPECS = list(filter(atari._supported_atari_env, gym.envs.registry.all()))
GYM_ATARI_ENV_SPECS = list(filter(atari._supported_atari_env, gym.registry.values()))
atari.register_atari_envs(GYM_ATARI_ENV_SPECS)
17 changes: 9 additions & 8 deletions src/seals/atari.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from typing import Dict, Iterable, Optional

import gym
import gymnasium as gym
from gymnasium.envs.registration import EnvSpec

from seals.util import (
AutoResetWrapper,
Expand Down Expand Up @@ -37,7 +38,7 @@ def _get_score_region(atari_env_id: str) -> Optional[MaskedRegionSpecifier]:

def make_atari_env(atari_env_id: str, masked: bool) -> gym.Env:
"""Fixed-length, optionally masked-score variant of a given Atari environment."""
env = AutoResetWrapper(gym.make(atari_env_id))
env: gym.Env = AutoResetWrapper(gym.make(atari_env_id))

if masked:
score_region = _get_score_region(atari_env_id)
Expand All @@ -59,15 +60,15 @@ def _not_ram_or_det(env_id: str) -> bool:
after_slash = slash_separated[-1]
hyphen_separated = after_slash.split("-")
assert len(hyphen_separated) > 1
not_ram = not ("ram" in hyphen_separated[1])
not_deterministic = not ("Deterministic" in env_id)
not_ram = "ram" not in hyphen_separated[1]
not_deterministic = "Deterministic" not in env_id
return not_ram and not_deterministic


def _supported_atari_env(gym_spec: gym.envs.registration.EnvSpec) -> bool:
def _supported_atari_env(gym_spec: EnvSpec) -> bool:
"""Checks if a gym Atari environment is one of the ones we will support."""
is_atari = gym_spec.entry_point == "gym.envs.atari:AtariEnv"
v5_and_plain = gym_spec.id.endswith("-v5") and not ("NoFrameskip" in gym_spec.id)
v5_and_plain = gym_spec.id.endswith("-v5") and "NoFrameskip" not in gym_spec.id
v4_and_no_frameskip = gym_spec.id.endswith("-v4") and "NoFrameskip" in gym_spec.id
return (
is_atari
Expand All @@ -76,7 +77,7 @@ def _supported_atari_env(gym_spec: gym.envs.registration.EnvSpec) -> bool:
)


def _seals_name(gym_spec: gym.envs.registration.EnvSpec, masked: bool) -> str:
def _seals_name(gym_spec: EnvSpec, masked: bool) -> str:
"""Makes a Gym ID for an Atari environment in the seals namespace."""
slash_separated = gym_spec.id.split("/")
name = "seals/" + slash_separated[-1]
Expand All @@ -88,7 +89,7 @@ def _seals_name(gym_spec: gym.envs.registration.EnvSpec, masked: bool) -> str:


def register_atari_envs(
gym_atari_env_specs: Iterable[gym.envs.registration.EnvSpec],
gym_atari_env_specs: Iterable[EnvSpec],
) -> None:
"""Register masked and unmasked wrapped gym Atari environments."""

Expand Down
Loading