-
Notifications
You must be signed in to change notification settings - Fork 4.3k
[WIP] Unity Environment Registry #3967
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
Conversation
[JIRA ticket](https://jira.unity3d.com/browse/MLA-997) [Design Document](https://docs.google.com/document/d/1bFQ3_oXsA80FMou8kwqYxC53kqG5L3i0mbTQUH4shY4/edit#) In This PR : Prototype of the Unity Environment Registry Uploaded the 3DBall and Basic Environments for mac only How to use on Python : ```python from mlagents_envs.registry import UnityEnvRegistry registry = UnityEnvRegistry() print(registry["3DBall"].description) env = registry["3DBall"].make() env.reset() for i in range(10): print(i) env.step() env.close() ```
platform dependent : It will only return a Unity executable compatible with the | ||
computer's OS. If no executable is found, None will be returned. | ||
""" | ||
_, bin_dir = get_tmp_dir() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have the final location of these be in a user-overridable directory, not a temp dir (since ideally they won't be temp).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tmp dir is fine for now. This is the way ai2-thor does it for example.
Here's a sketch of what I had in mind for the remote yaml files:
|
- UnityEnvRegistry is no longer static and needs to be instantiated - Providing a default_registry that will contains our environments - Added a functionality to register RemoteRegistryEntry with a yaml file
Made some updates :
yaml file looks like : environments:
- 3DBall:
expected_reward: 100
description: | ## 3DBall: 3D Balance Ball
...
linux_url: null
darwin_url: https://storage.googleapis.com/mlagents-test-environments/1.0.0/darwin/3DBall.zip
win_url: null
- Basic:
expected_reward: 0.93
description: | ## Basic
...
linux_url: null
darwin_url: https://storage.googleapis.com/mlagents-test-environments/1.0.0/darwin/Basic.zip
win_url: null
|
ml-agents-envs/setup.py
Outdated
@@ -51,6 +51,7 @@ def run(self): | |||
"numpy>=1.14.1,<2.0", | |||
"Pillow>=4.2.1", | |||
"protobuf>=3.6", | |||
"pyyaml", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not too happy about this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not specify a lower bound for pyyaml version ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied this from the mlagents setup.py file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copying from mlagents setup.py doesn't make it correct. I suggest having a lower bound on the pyyaml version in both places.
…he url in its name to make sure the right environment is opened and not just the one present. Useful if environments are renamed
print("") | ||
|
||
# Clean up zip | ||
print_progress(f" Cleaning up {name}", 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use a logger instead of print statements in lines 117,118,123,126
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replaced one of the calls but I want a progress bar and logger can't do that
Converts a local yaml file into a Python dictionary | ||
""" | ||
with open(path) as data_file: | ||
return yaml.safe_load(data_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might want to handle an exception here in case yaml.safe_load throws an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is wrong with raising that error? I don't want to suppress it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firstly there is nothing wrong in what you did. Secondly, raising an exception allows you to give a more informative message to the user instead of a generic error message that comes from python. It's more of a matter of coding style rather than correctness.
It was just a suggestion to begin with :)
ml-agents-envs/setup.py
Outdated
@@ -51,6 +51,7 @@ def run(self): | |||
"numpy>=1.14.1,<2.0", | |||
"Pillow>=4.2.1", | |||
"protobuf>=3.6", | |||
"pyyaml", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not specify a lower bound for pyyaml version ?
|
||
# Download zip | ||
try: | ||
request = urllib.request.urlopen(url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please pass a timeout here, otherwise it could hang indefinitely. I'd say 30 seconds as a default, with optional parameters to override?
logger.debug( | ||
f"Local environment {name} not found, downloading environment from {url}" | ||
) | ||
download_and_extract_zip(url, name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Connection errors will raise from here and aren't caught. Since these might be transient errors and not the users fault, we should catch them and return null (or even better, retry a few times).
with open(zip_file_path, "wb") as zip_file: | ||
downloaded = 0 | ||
while True: | ||
buffer = request.read(BLOCK_SIZE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same vein, pretty sure this could fail sporadically; needs some better error handling.
Co-authored-by: andrewcoh <[email protected]>
- ... | ||
``` | ||
|
||
Your users can now use your environment with the following code : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be made clear that they are not pushing these builds to our storage but they must host it on their own? Is there another step to use the new env i.e. pip install foo-env
in gym or is this beyond the scope of this WIP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no additional step. No need to pip install anything, just get the url of the yaml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if you have a new env do you submit a PR to our repo to have it added to the registry? Or do you need to go to a fork?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so it seems the documentation is not clear. Please advise on how to make more explicit.
If you made a brand new environment, you need to :
- Compile it into an executable
- Zip the executable
- Upload the executable to YOUR OWN hosting service (example : gcs)
- Create a yaml file that contains the url to the zip file
- Upload the yaml file to hosting service
Once this is done, to share your environment, all you need to do is advertise the URL to the yaml. If a user wants your environment, all they have to do is call
env_registry = UnityEnvRegistry()
env_registry.register_from_yaml("your-url-here")
And they will have your environment.
No PR, no fork, no pip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrew is this confusing? Should I change the documentation to give more details ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that makes sense. I was being dense. Also, thats not me^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😨
I can come in another iteration, but I think we should have some notion of versioning of a given environment (separate from the communicator version) to indicate changes/iterations on the scene itself. |
I tried
I got None in the stdout. |
@yijiezh ml-agents/ml-agents-envs/mlagents_envs/base_env.py Lines 375 to 379 in c75eacb
Please create a new issue (or forum thread) if you have more problems. |
JIRA ticket
Design Document
In This PR : Prototype of the Unity Environment Registry
Uploaded the 3DBall and Basic Environments for mac only
How to use on Python :
Types of change(s)
Checklist