Farama-Foundation / Gymnasium

An API standard for single-agent reinforcement learning environments, with popular reference environments and related utilities (formerly Gym)
https://gymnasium.farama.org
MIT License
7.5k stars 840 forks source link

make_vec(...) will raise error "AttributeError: can't set attribute", while vector.make(..) doesn't for customized env #967

Open BruceGeLi opened 8 months ago

BruceGeLi commented 8 months ago

Describe the bug

Hi,

I have some customized RL envs, and I want to create asychronized env vector to make them run in parallel. Firstly, I used the gymnasium.vector.make(...), and there is some warning saying that it will be deprecated and replaced by the gymnasium.make_vec() function. Thus I decided to use the new one.

My code looks like:

import fancy_gym
import gymnasium as gym

env_id = "metaworld/button-press-v2"
num_envs = 8
render = False

# Buggy
env = gym.make_vec(id=env_id, num_envs=num_envs, vectorization_mode="async",
                       render_mode='human' if render else None)

# Works fine
env = gym.vector.make(id=env_id, num_envs=num_envs,
                          render_mode='human' if render else None)

The former make function will raise an error, as

  File "/home/lige/Software/mamba/envs/tce/lib/python3.8/site-packages/gymnasium/envs/registration.py", line 977, in _create_env
    _env.spec = spec_
AttributeError: can't set attribute

I am not sure if the issue comes from my customized env, as it works ok with the old function. To reproduce the bug easily, you may need to install the two packages:

conda create -n test_gym python=3.8
conda activate test_gym

pip install git+https://github.com/Farama-Foundation/Metaworld.git@master#egg=metaworld
pip install fancy_gym

where the metaworld is from your organization and fancy_gym is our custimozed RL wrappers...

Code example

import fancy_gym
import gymnasium as gym

env_id = "metaworld/button-press-v2"
num_envs = 8
render = False

# Buggy
env = gym.make_vec(id=env_id, num_envs=num_envs, vectorization_mode="async",
                       render_mode='human' if render else None)

# Works fine
env = gym.vector.make(id=env_id, num_envs=num_envs,
                          render_mode='human' if render else None)

System info

gymnasium: 0.29.1, installed as a dependency of fancy_gym package (via pip) Ubuntu 22.04 conda 23.11.0 python 3.8

Additional context

Thank you in advance.

Checklist

Kallinteris-Andreas commented 8 months ago

Does the issue persist with gymnasium==1.0.0a1? (note: metaworld may break though)

BruceGeLi commented 8 months ago

Hi, thanks for your reply.

Beyond this issue, I actually found some other weird bugs in v0.29, such as the asych env vector is actually not asych. The running time is propotional to the num of envs :(

I see v1.0.0a1 gets a lot of update to these vector envs. So, I will give a try, but it will take some time from us to adapt our code base to v1.0.0a1.

pseudo-rnd-thoughts commented 8 months ago

My guess is that the environment used has a wrapper applied to it, and you can't set the spec for a wrapper (property reasons). Therefore, I would guess this is a bug but I don't think we will be releasing anymore v0.29 versions to fix this sadly. I would use gym.vector.make in the meantime. Hopefully gymnasium.make_vec will be fix this in the next release.

pseudo-rnd-thoughts commented 8 months ago

My guess is that the environment used has a wrapper applied to it, and you can't set the spec for a wrapper (property reasons). Therefore, I would guess this is a bug but I don't think we will be releasing anymore v0.29 versions to fix this sadly. I would use gym.vector.make in the meantime. Hopefully gymnasium.make_vec will be fix this in the next release.

I'm wrong, this isn't the problem

class CustomWrapper(gym.Wrapper):
    def __init__(self, **kwargs):
        super().__init__(gym.make("CartPole-v1", disable_env_checker=True, **kwargs))

# the entry_point is directly the wrapper class which poses an issue as the Wrapper has `metadata` using a property
gym.register("TestEnv-v0", CustomWrapper)
gym.make_vec("TestEnv-v0", num_envs=1)
del gym.registry["TestEnv-v0"]

So I don't know what the issue is. @BruceGeLi When you updated to v1.0.0, let us know if you still have an issue

Zhaohhya commented 8 months ago

I've found similar problems. I'm following the warning WARN: gymnasium.vector.make(...) is deprecated and will be replaced by gymnasium.make_vec(...) in v1.0 Using the following code envs = gym.make_vec("InvertedPendulum-v4", num_envs = 3, max_episode_steps=600) it will raise an error, as

  File "C:\Users\87182\anaconda3\envs\gymnasium\lib\site-packages\gymnasium\wrappers\record_episode_statistics.py", line 98, in step
    self.episode_returns += rewards
ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (3,)

Change back to the original function envs = gym.vector.make("InvertedPendulum-v4", num_envs = 3, max_episode_steps=600) and it worked

BruceGeLi commented 8 months ago

My guess is that the environment used has a wrapper applied to it, and you can't set the spec for a wrapper (property reasons). Therefore, I would guess this is a bug but I don't think we will be releasing anymore v0.29 versions to fix this sadly. I would use gym.vector.make in the meantime. Hopefully gymnasium.make_vec will be fix this in the next release.

I'm wrong, this isn't the problem

class CustomWrapper(gym.Wrapper):
    def __init__(self, **kwargs):
        super().__init__(gym.make("CartPole-v1", disable_env_checker=True, **kwargs))

# the entry_point is directly the wrapper class which poses an issue as the Wrapper has `metadata` using a property
gym.register("TestEnv-v0", CustomWrapper)
gym.make_vec("TestEnv-v0", num_envs=1)
del gym.registry["TestEnv-v0"]

So I don't know what the issue is. @BruceGeLi When you updated to v1.0.0, let us know if you still have an issue

Thanks, we will have a try later and will report the result, but will take some time I think.

pseudo-rnd-thoughts commented 8 months ago

envs = gym.make_vec("InvertedPendulum-v4", num_envs = 3, max_episode_steps=600)

@Zhaohhya Your example doesn't produce an error, could you provide a large example that raises an error