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

Add EnvPool support (as VecEnv subclass) #355

Open
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

qgallouedec
Copy link
Collaborator

@qgallouedec qgallouedec commented Feb 9, 2023

Description

Based on #307, but use VecEnv subclass instead of VecEnvWrapper.
VecEnvWrapper assumes the wrapped env of an instance of VecEnv, which is not the case of EnvPool. IMO, using the VecEnv class directly is therefore a better option, and the implementation is not more complex.

Motivation and Context

  • I have raised an issue to propose this change (required for new features and bug fixes)

closes #241

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (update in the documentation)

Checklist:

  • I've read the CONTRIBUTION guide (required)
  • I have updated the changelog accordingly (required).
  • My change requires a change to the documentation.
  • I have updated the tests accordingly (required for a bug fix or a new feature).
  • I have updated the documentation accordingly.
  • I have reformatted the code using make format (required)
  • I have checked the codestyle using make check-codestyle and make lint (required)
  • I have ensured make pytest and make type both pass. (required)

Note: we are using a maximum length of 127 characters per line

@qgallouedec
Copy link
Collaborator Author

qgallouedec commented Feb 9, 2023

Here are some speed results with Breakout and PPO. I can't understand why envpool is only slightly faster than dummy vec env. @araffin, @Trinkle23897 any insight?
Figure_1
(y axis is fps)

@araffin araffin mentioned this pull request Feb 10, 2023
13 tasks
@qgallouedec
Copy link
Collaborator Author

@araffin what do you think about moving this to sb3 (insert it to make_vec_env)?
And make envpool an optional dependency of sb3.

@araffin
Copy link
Member

araffin commented Feb 10, 2023

what do you think about moving this to sb3 (insert it to make_vec_env)?

not sure about it.
My main concern is that it only supports half the thing that a VecEnv can do (notably, it doesn't support gym wrappers).
I think it would make more sense in sb3 contrib or here in the RL Zoo (especially as it is a package now, so people can re-use it easily if needed).

@qgallouedec
Copy link
Collaborator Author

My main concern is that it only supports half the thing that a VecEnv can do

Makes sense, we will need to update the sb3 doc btw.

@araffin araffin self-requested a review March 2, 2023 10:11
@qgallouedec
Copy link
Collaborator Author

@araffin, before merging, we need to explain this #355 (comment)

if self.env_kwargs:
warnings.warn(
"EnvPool does not support env_kwargs, it will be ignored. "
"To pass keyword argument to envpool, use vec_env_kwargs instead."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have vec_env_kwargs available in the cli, but we should add it.

Comment on lines 619 to 624
if (
"Neck" in self.env_name.gym_id
or self.is_robotics_env(self.env_name.gym_id)
or "parking-v0" in self.env_name.gym_id
and len(self.monitor_kwargs) == 0 # do not overwrite custom kwargs
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (
"Neck" in self.env_name.gym_id
or self.is_robotics_env(self.env_name.gym_id)
or "parking-v0" in self.env_name.gym_id
and len(self.monitor_kwargs) == 0 # do not overwrite custom kwargs
):
if (
self.is_robotics_env(self.env_name.gym_id)
or "parking-v0" in self.env_name.gym_id
and len(self.monitor_kwargs) == 0 # do not overwrite custom kwargs
):

"Neck" in self.env_name.gym_id was for personal use and should be removed.

@@ -153,6 +153,13 @@ def train() -> None:
default=False,
help="if toggled, display a progress bar using tqdm and rich",
)
parser.add_argument(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing: a section in the readme, I will try to create a real doc soon (the readme is way too long now).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc is there

from stable_baselines3.common.vec_env.base_vec_env import VecEnvObs, VecEnvStepReturn

# Used when we want to access one or more VecEnv
VecEnvIndices = Union[None, int, Iterable[int]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't have that type hint defined in SB3?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in base_with_env. I don't remember why I redefined it here. I probably should have imported it

@araffin
Copy link
Member

araffin commented Mar 2, 2023

Here are some speed results with Breakout and PPO. I can't understand why envpool is only slightly faster than dummy vec env. @araffin, @Trinkle23897 any insight?

So, it seems to depends on the env, but yes it is surprising.

I also have envpool slower than SubProcVecEnv on my machine with python 3.7 (but not as slow as reported here).

But on MuJoCo env, envpool is the fastest for me:

Envpool: ~4100 fps

CUDA_VISIBLE_DEVICES= OMP_NUM_THREADS=2 python -m rl_zoo3.train --algo a2c --env HalfCheetah-v3 --verbose 0 --eval-freq -1 -P -envpool -params n_envs:4

vs
Subproc: ~3400 fps

CUDA_VISIBLE_DEVICES= OMP_NUM_THREADS=2 python -m rl_zoo3.train --algo a2c --env HalfCheetah-v3 --verbose 0 --eval-freq -1 -P -params n_envs:4 --vec-env subproc

vs

Dummy: ~3600 fps

CUDA_VISIBLE_DEVICES= OMP_NUM_THREADS=2 python -m rl_zoo3.train --algo a2c --env HalfCheetah-v3 --verbose 0 --eval-freq -1 -P -params n_envs:4 --vec-env dummy

@Trinkle23897
Copy link

Can you use py-spy to have a profiling result?

@araffin
Copy link
Member

araffin commented Mar 2, 2023

Can you use py-spy to have a profiling result?

Profiles: This is for sub process:

profile_subproc

For envpool, I think py-spy had a segfault:
profile_envpool

@Trinkle23897
Copy link

It seems like there are a lot of "importlib" calls in rl_zoo3.train with envpool. That should not be the case and I believe something is wrong. Did you accidentally call envpool with multiple python processes/threads?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Integrate EnvPool
3 participants