Commit b7e1a791 authored by pfrl_rainbow's avatar pfrl_rainbow

Initial commit

parents
data/
shared/
logs/
.gradle/
*.pyc
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
This diff is collapsed.
{
"challenge_id": "aicrowd-neurips-2020-minerl-challenge",
"grader_id": "aicrowd-neurips-2020-minerl-challenge",
"authors": ["aicrowd-bot"],
"tags": "change-me",
"description": "Test Model for MineRL Challenge",
"gpu": false
}
#!/usr/bin/env python
import crowdai_api
import os
import logging
########################################################################
# Instatiate Event Notifier
########################################################################
crowdai_events = crowdai_api.events.CrowdAIEvents()
current_phase = None
training_progress = 0.0
def inference_start():
########################################################################
# Register Inference Start event
########################################################################
logging.info("Inference Start...")
global current_phase
current_phase = "inference"
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="inference_started",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:inference_started"
}
)
def inference_end():
########################################################################
# Register Inference End event
########################################################################
logging.info("Inference End...")
global current_phase
current_phase = None
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="inference_ended",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:inference_ended"
}
)
def inference_error():
########################################################################
# Register Inference Error event
########################################################################
logging.error("Inference Failed...")
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="inference_error",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:inference_error"
}
)
def training_start():
########################################################################
# Register Training Start event
########################################################################
logging.info("Training Start...")
global current_phase
current_phase = "training"
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="training_started",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:training_started"
}
)
def training_end():
########################################################################
# Register Training End event
########################################################################
logging.info("Training End...")
register_progress(1.0)
global current_phase
current_phase = None
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="training_ended",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:training_ended"
}
)
def training_error():
########################################################################
# Register Training Error event
########################################################################
logging.error("Training Failed...")
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="training_error",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:training_error"
}
)
def register_progress(progress):
########################################################################
# Register Evaluation Progress event
# progress : float [0, 1]
########################################################################
logging.info("Progress : {}".format(progress))
global training_progress, current_phase
if current_phase is None:
raise Exception('Please register current phase by calling `training_start` \
or `inference_start` before sending progress.')
if current_phase == "training":
if progress < training_progress:
logging.warn('Invalid progress update to %f while you are already \
at %f. Skipping it...', progress, training_progress)
return
training_progress = progress
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_INFO,
message="register_progress",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:register_progress",
"training_progress" : training_progress
}
)
def submit(payload={}):
########################################################################
# Register Evaluation Complete event
########################################################################
logging.info("AIcrowd Submit")
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_SUCCESS,
message="submit",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:submit",
},
blocking=True
)
def execution_error(error):
########################################################################
# Register Evaluation Complete event
########################################################################
crowdai_events.register_event(
event_type=crowdai_events.CROWDAI_EVENT_ERROR,
message="execution_error",
payload={ #Arbitrary Payload
"event_type": "minerl_challenge:execution_error",
"error" : error
},
blocking=True
)
curl
git
vim
ssh
gcc
python-dev
libsm6
libxext6
libxrender-dev
libglib2.0-0
openjdk-8-jdk
xvfb
x11vnc
freeglut3-dev
libx11-6
python-opengl
x11-xserver-utils
import aicrowd_helper
import train
import test
import os
EVALUATION_RUNNING_ON = os.getenv('EVALUATION_RUNNING_ON', None)
EVALUATION_STAGE = os.getenv('EVALUATION_STAGE', 'all')
EXITED_SIGNAL_PATH = os.getenv('EXITED_SIGNAL_PATH', 'shared/exited')
# Training Phase
if EVALUATION_STAGE in ['all', 'training']:
aicrowd_helper.training_start()
try:
train.main()
aicrowd_helper.training_end()
except Exception as e:
aicrowd_helper.training_error()
print(e)
# Testing Phase
if EVALUATION_STAGE in ['all', 'testing']:
if EVALUATION_RUNNING_ON in ['local']:
try:
os.remove(EXITED_SIGNAL_PATH)
except FileNotFoundError:
pass
aicrowd_helper.inference_start()
try:
test.main()
aicrowd_helper.inference_end()
except Exception as e:
aicrowd_helper.inference_error()
print(e)
if EVALUATION_RUNNING_ON in ['local']:
from pathlib import Path
Path(EXITED_SIGNAL_PATH).touch()
# Launch instance manager
if EVALUATION_STAGE in ['manager']:
from minerl.env.malmo import launch_instance_manager
launch_instance_manager()
import json
import select
import time
import logging
import os
import threading
from typing import Callable
import aicrowd_helper
import gym
import minerl
import abc
import numpy as np
import coloredlogs
coloredlogs.install(logging.DEBUG)
# All the evaluations will be evaluated on MineRLObtainDiamondVectorObf-v0 environment
MINERL_GYM_ENV = os.getenv('MINERL_GYM_ENV', 'MineRLObtainDiamondVectorObf-v0')
MINERL_MAX_EVALUATION_EPISODES = int(os.getenv('MINERL_MAX_EVALUATION_EPISODES', 5))
# Parallel testing/inference, **you can override** below value based on compute
# requirements, etc to save OOM in this phase.
EVALUATION_THREAD_COUNT = int(os.getenv('EPISODES_EVALUATION_THREAD_COUNT', 2))
class EpisodeDone(Exception):
pass
class Episode(gym.Env):
"""A class for a single episode.
"""
def __init__(self, env):
self.env = env
self.action_space = env.action_space
self.observation_space = env.observation_space
self._done = False
def reset(self):
if not self._done:
return self.env.reset()
def step(self, action):
s,r,d,i = self.env.step(action)
if d:
self._done = True
raise EpisodeDone()
else:
return s,r,d,i
# DO NOT CHANGE THIS CLASS, THIS IS THE BASE CLASS FOR YOUR AGENT.
class MineRLAgentBase(abc.ABC):
"""
To compete in the competition, you are required to implement a
SUBCLASS to this class.
YOUR SUBMISSION WILL FAIL IF:
* Rename this class
* You do not implement a subclass to this class
This class enables the evaluator to run your agent in parallel,
so you should load your model only once in the 'load_agent' method.
"""
@abc.abstractmethod
def load_agent(self):
"""
This method is called at the beginning of the evaluation.
You should load your model and do any preprocessing here.
THIS METHOD IS ONLY CALLED ONCE AT THE BEGINNING OF THE EVALUATION.
DO NOT LOAD YOUR MODEL ANYWHERE ELSE.
"""
raise NotImplementedError()
@abc.abstractmethod
def run_agent_on_episode(self, single_episode_env : Episode):
"""This method runs your agent on a SINGLE episode.
You should just implement the standard environment interaction loop here:
obs = env.reset()
while not done:
env.step(self.agent.act(obs))
...
NOTE: This method will be called in PARALLEL during evaluation.
So, only store state in LOCAL variables.
For example, if using an LSTM, don't store the hidden state in the class
but as a local variable to the method.
Args:
env (gym.Env): The env your agent should interact with.
"""
raise NotImplementedError()
#######################
# YOUR CODE GOES HERE #
#######################
class MineRLMatrixAgent(MineRLAgentBase):
"""
An example random agent.
Note, you MUST subclass MineRLAgentBase.
"""
def load_agent(self):
"""In this example we make a random matrix which
we will use to multiply the state by to produce an action!
This is where you could load a neural network.
"""
# Some helpful constants from the environment.
flat_video_obs_size = 64*64*3
obs_size = 64
ac_size = 64
self.matrix = np.random.random(size=(ac_size, flat_video_obs_size + obs_size))*2 -1
self.flatten_obs = lambda obs: np.concatenate([obs['pov'].flatten()/255.0, obs['vector'].flatten()])
self.act = lambda flat_obs: {'vector': np.clip(self.matrix.dot(flat_obs), -1,1)}
def run_agent_on_episode(self, single_episode_env : Episode):
"""Runs the agent on a SINGLE episode.
Args:
single_episode_env (Episode): The episode on which to run the agent.
"""
obs = single_episode_env.reset()
done = False
while not done:
obs,reward,done,_ = single_episode_env.step(self.act(self.flatten_obs(obs)))
class MineRLRandomAgent(MineRLAgentBase):
"""A random agent"""
def load_agent(self):
pass # Nothing to do, this agent is a random agent.
def run_agent_on_episode(self, single_episode_env : Episode):
obs = single_episode_env.reset()
done = False
while not done:
random_act = single_episode_env.action_space.sample()
single_episode_env.step(random_act)
#####################################################################
# IMPORTANT: SET THIS VARIABLE WITH THE AGENT CLASS YOU ARE USING #
######################################################################
AGENT_TO_TEST = MineRLMatrixAgent # MineRLMatrixAgent, MineRLRandomAgent, YourAgentHere
####################
# EVALUATION CODE #
####################
def main():
agent = AGENT_TO_TEST()
assert isinstance(agent, MineRLAgentBase)
agent.load_agent()
assert MINERL_MAX_EVALUATION_EPISODES > 0
assert EVALUATION_THREAD_COUNT > 0
# Create the parallel envs (sequentially to prevent issues!)
envs = [gym.make(MINERL_GYM_ENV) for _ in range(EVALUATION_THREAD_COUNT)]
episodes_per_thread = [MINERL_MAX_EVALUATION_EPISODES // EVALUATION_THREAD_COUNT for _ in range(EVALUATION_THREAD_COUNT)]
episodes_per_thread[-1] += MINERL_MAX_EVALUATION_EPISODES - EVALUATION_THREAD_COUNT *(MINERL_MAX_EVALUATION_EPISODES // EVALUATION_THREAD_COUNT)
# A simple funciton to evaluate on episodes!
def evaluate(i, env):
print("[{}] Starting evaluator.".format(i))
for i in range(episodes_per_thread[i]):
try:
agent.run_agent_on_episode(Episode(env))
except EpisodeDone:
print("[{}] Episode complete".format(i))
pass
evaluator_threads = [threading.Thread(target=evaluate, args=(i, envs[i])) for i in range(EVALUATION_THREAD_COUNT)]
for thread in evaluator_threads:
thread.start()
# wait fo the evaluation to finish
for thread in evaluator_threads:
thread.join()
if __name__ == "__main__":
main()
# Simple env test.
import json
import select
import time
import logging
import os
import aicrowd_helper
import gym
import minerl
from utility.parser import Parser
import coloredlogs
coloredlogs.install(logging.DEBUG)
# All the evaluations will be evaluated on MineRLObtainDiamond-v0 environment
MINERL_GYM_ENV = os.getenv('MINERL_GYM_ENV', 'MineRLObtainDiamondVectorObf-v0')
# You need to ensure that your submission is trained in under MINERL_TRAINING_MAX_STEPS steps
MINERL_TRAINING_MAX_STEPS = int(os.getenv('MINERL_TRAINING_MAX_STEPS', 8000000))
# You need to ensure that your submission is trained by launching less than MINERL_TRAINING_MAX_INSTANCES instances
MINERL_TRAINING_MAX_INSTANCES = int(os.getenv('MINERL_TRAINING_MAX_INSTANCES', 5))
# You need to ensure that your submission is trained within allowed training time.
# Round 1: Training timeout is 15 minutes
# Round 2: Training timeout is 4 days
MINERL_TRAINING_TIMEOUT = int(os.getenv('MINERL_TRAINING_TIMEOUT_MINUTES', 4*24*60))
# The dataset is available in data/ directory from repository root.
MINERL_DATA_ROOT = os.getenv('MINERL_DATA_ROOT', 'data/')
# Optional: You can view best effort status of your instances with the help of parser.py
# This will give you current state like number of steps completed, instances launched and so on. Make your you keep a tap on the numbers to avoid breaching any limits.
parser = Parser('performance/',
allowed_environment=MINERL_GYM_ENV,
maximum_instances=MINERL_TRAINING_MAX_INSTANCES,
maximum_steps=MINERL_TRAINING_MAX_STEPS,
raise_on_error=False,
no_entry_poll_timeout=600,
submission_timeout=MINERL_TRAINING_TIMEOUT*60,
initial_poll_timeout=600)
def main():
"""
This function will be called for training phase.
"""
# How to sample minerl data is document here:
# http://minerl.io/docs/tutorials/data_sampling.html
data = minerl.data.make(MINERL_GYM_ENV, data_dir=MINERL_DATA_ROOT)
# Sample code for illustration, add your training code below
env = gym.make(MINERL_GYM_ENV)
# actions = [env.action_space.sample() for _ in range(10)] # Just doing 10 samples in this example
# xposes = []
# for _ in range(1):
# obs = env.reset()
# done = False
# netr = 0
# # Limiting our code to 1024 steps in this example, you can do "while not done" to run till end
# while not done:
# To get better view in your training phase, it is suggested
# to register progress continuously, example when 54% completed
# aicrowd_helper.register_progress(0.54)
# To fetch latest information from instance manager, you can run below when you want to know the state
#>> parser.update_information()
#>> print(parser.payload)
# .payload: provide AIcrowd generated json
# Example: {'state': 'RUNNING', 'score': {'score': 0.0, 'score_secondary': 0.0}, 'instances': {'1': {'totalNumberSteps': 2001, 'totalNumberEpisodes': 0, 'currentEnvironment': 'MineRLObtainDiamond-v0', 'state': 'IN_PROGRESS', 'episodes': [{'numTicks': 2001, 'environment': 'MineRLObtainDiamond-v0', 'rewards': 0.0, 'state': 'IN_PROGRESS'}], 'score': {'score': 0.0, 'score_secondary': 0.0}}}}
# .current_state: provide indepth state information avaiable as dictionary (key: instance id)
# Save trained model to train/ directory
# Training 100% Completed
aicrowd_helper.register_progress(1)
#env.close()
if __name__ == "__main__":
main()
#!/bin/bash
if [ -e environ_secret.sh ]
then
source utility/environ_secret.sh
else
source utility/environ.sh
fi
if ! [ -x "$(command -v aicrowd-repo2docker)" ]; then
echo 'Error: aicrowd-repo2docker is not installed.' >&2
echo 'Please install it using requirements.txt or pip -U install aicrowd-repo2docker' >&2
exit 1
fi
# Expected Env variables : in environ.sh
REPO2DOCKER="$(which aicrowd-repo2docker)"
sudo ${REPO2DOCKER} --no-run \
--user-id 1001 \
--user-name aicrowd \
--image-name ${IMAGE_NAME}:${IMAGE_TAG} \
--debug .
#sudo docker push "${IMAGE_NAME}:${IMAGE_TAG}"
#!/bin/bash
# This script run your submission inside a docker image, this is identical in termrs of
# how your code will be executed on AIcrowd platform
if [ -e environ_secret.sh ]
then
echo "Note: Gathering environment variables from environ_secret.sh"
source utility/environ_secret.sh
else
echo "Note: Gathering environment variables from environ.sh"
source utility/environ.sh
fi
# Skip building docker image on run, by default each run means new docker image build
if [[ " $@ " =~ " --no-build " ]]; then
echo "Skipping docker image build"
else
echo "Building docker image, for skipping docker image build use \"--no-build\""
./utility/docker_build.sh
fi
ARGS="${@}"
# Expected Env variables : in environ.sh
if [[ " $@ " =~ " --nvidia " ]]; then
sudo nvidia-docker run \
--net=host \
--user 0 \
-v $(PWD)/data:/home/aicrowd/data \
-v $(PWD)/performance:/home/aicrowd/performance \
-v $(PWD)/.gradle:/home/aicrowd/.gradle \
-e CROWDAI_DEBUG_MODE=True \
-it ${IMAGE_NAME}:${IMAGE_TAG} \
/bin/bash -c "echo \"Staring docker evaluation...\"; xvfb-run -a ./utility/evaluation_locally.sh ${ARGS}"
else
echo "NOTE: To run your submission with nvidia drivers locally, use \"--nvidia\" with this script"
sudo docker run \
--net=host \
-v $(PWD)/data:/home/aicrowd/data \
-v $(PWD)/performance:/home/aicrowd/performance \
-v $(PWD)/.gradle:/home/aicrowd/.gradle \
-e CROWDAI_DEBUG_MODE=True \
-it ${IMAGE_NAME}:${IMAGE_TAG} \
/bin/bash -c "echo \"Staring docker evaluation...\"; xvfb-run -a ./utility/evaluation_locally.sh ${ARGS}"
fi
#!/bin/bash
# This script run your submission inside a docker image, this is identical in termrs of
# how your code will be executed on AIcrowd platform
if [ -e environ_secret.sh ]
then
echo "Note: Gathering environment variables from environ_secret.sh"
source utility/environ_secret.sh
else
echo "Note: Gathering environment variables from environ.sh"
source utility/environ.sh
fi
# Skip building docker image on run, by default each run means new docker image build
if [[ " $@ " =~ " --no-build " ]]; then
echo "Skipping docker image build"
else
echo "Building docker image, for skipping docker image build use \"--no-build\""
./utility/docker_build.sh
fi
# Expected Env variables : in environ.sh
if [[ " $@ " =~ " --nvidia " ]]; then
sudo nvidia-docker run \
--net=host \
--user 0 \
-e CROWDAI_IS_GRADING=True \
-e CROWDAI_DEBUG_MODE=True \
-it ${IMAGE_NAME}:${IMAGE_TAG} \
/bin/bash
else
echo "To run your submission with nvidia drivers, use \"--nvidia\" with this script"
sudo docker run \
--net=host \
--user 0 \
-e CROWDAI_IS_GRADING=True \