98 votes

Comment faire pour exécuter OpenAI salle de sport .render() sur un serveur

Je suis en cours d'exécution d'un script python 2.7 sur un p2.xlarge AWS serveur par le biais de Jupyter (Ubuntu 14.04). Je voudrais être en mesure de rendre mes simulations.

De travail minimale exemple

import gym
env = gym.make('CartPole-v0')
env.reset()
env.render()

env.render() fait (entre autres choses) les erreurs suivantes:

...
HINT: make sure you have OpenGL install. On Ubuntu, you can run 
'apt-get install python-opengl'. If you're running on a server, 
you may need a virtual frame buffer; something like this should work: 
'xvfb-run -s \"-screen 0 1400x900x24\" python <your_script.py>'")
...
NoSuchDisplayException: Cannot connect to "None"

Je voudrais être en mesure de voir les simulations. Il serait idéal si je pouvais le faire en ligne, mais toute méthode d'affichage, ce serait bien.

Edit: C'est seulement un problème avec certains environnements, comme les classiques de contrôle.


Mise À Jour, Je

Inspiré par ce que j'ai essayé le suivant, au lieu de l' xvfb-run -s \"-screen 0 1400x900x24\" python <your_script.py> (dont je ne pouvais pas aller au travail).

xvfb-run -a jupyter notebook

Exécute le script original maintenant, je reçois à la place

GLXInfoException: pyglet requires an X server with GLX

Mise à jour II

Question #154 semble pertinent. J'ai essayé de désactiver le pop-up, et de créer directement les couleurs RVB

import gym
env = gym.make('CartPole-v0')
env.reset()

img = env.render(mode='rgb_array', close=True)  
print(type(img)) # <--- <type 'NoneType'>

img = env.render(mode='rgb_array', close=False) # <--- ERROR
print(type(img)) 

Je reçois ImportError: cannot import name gl_info.


Mise à jour III

Avec l'inspiration de @Torxed j'ai essayé de créer un fichier vidéo, et ensuite rendu (une solution satisfaisante).

En utilisant le code de 'Enregistrement et le téléchargement des résultats'

import gym

env = gym.make('CartPole-v0')
env.monitor.start('/tmp/cartpole-experiment-1', force=True)
observation = env.reset()
for t in range(100):
#    env.render()
    print(observation)
    action = env.action_space.sample()
    observation, reward, done, info = env.step(action)
    if done:
        print("Episode finished after {} timesteps".format(t+1))
        break

env.monitor.close()

J'ai essayé de suivre vos conseils, mais j'ai reçu ImportError: cannot import name gl_info d'lors de l'exécution d' env.monitor.start(....

De ma compréhension du problème, c'est que OpenAI utilise pyglet, et pyglet "besoins" d'un écran afin de calculer les couleurs RVB de l'image qui doit être rendu. Il est donc nécessaire de truc python à penser qu'il y est un moniteur connecté


Mise à jour IV

Pour info, il existe des solutions en ligne à l'aide de bourdon qui semblent fonctionner. Cela devrait fonctionner si vous avez le contrôle sur le serveur, mais depuis AWS courir dans une machine virtuelle, je ne pense pas que vous pouvez utiliser.


Mise À Jour V

Simplement, si vous avez ce problème, et ne sais pas quoi faire (comme moi) l'état de la plupart des environnements sont assez simples que vous pouvez créer votre propre rendu mécanisme. Pas très satisfaisant, mais.. vous savez.

45voto

A obtenu une solution simple de travail:

CartPole

Si sur un serveur linux, ouvrez jupyter avec

$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook

Dans Jupyter

import matplotlib.pyplot as plt
%matplotlib inline
from IPython import display

Après chaque étape

def show_state(env, step=0, info=""):
    plt.figure(3)
    plt.clf()
    plt.imshow(env.render(mode='rgb_array'))
    plt.title("%s | Step: %d %s" % (env._spec.id,step, info))
    plt.axis('off')

    display.clear_output(wait=True)
    display.display(plt.gcf())

Remarque: si votre environnement n'est pas unwrapped, pass env.env de show_state.

31voto

Nathan Points 1050

Cette GitHub l'émission a donné une réponse qui a très bien fonctionné pour moi. C'est bien car il ne nécessite pas de dépendances supplémentaires (je suppose que vous avez déjà matplotlib) ou de la configuration du serveur.

Il suffit d'exécuter, par exemple:

import gym
import matplotlib.pyplot as plt
%matplotlib inline

env = gym.make('Breakout-v0') # insert your favorite environment
render = lambda : plt.imshow(env.render(mode='rgb_array'))
env.reset()
render()

À l'aide de mode='rgb_array' vous donne en un numpy.ndarray avec les valeurs RVB pour chaque position, et matplotlibs' imshow (ou d'autres méthodes) affiche bien.

Notez que si vous vous êtes rendu plusieurs fois dans la même cellule, cette solution permettra de tracer une image distincte à chaque fois. Ce n'est probablement pas ce que vous voulez. Je vais essayer de mettre à jour si je l'ai trouver une bonne solution pour cela.

Mise à jour pour rendre plusieurs fois dans une cellule

Basé sur cette StackOverflow réponse, voici un travail extrait de (notez qu'il peut y avoir des moyens plus efficaces de faire cela avec un interactives de la parcelle; de cette manière, semble un peu de lag sur ma machine):

import gym
from IPython import display
import matplotlib.pyplot as plt
%matplotlib inline

env = gym.make('Breakout-v0')
env.reset()
for _ in range(100):
    plt.imshow(env.render(mode='rgb_array'))
    display.display(plt.gcf())
    display.clear_output(wait=True)
    action = env.action_space.sample()
    env.step(action)

Mise à jour afin d'accroître l'efficacité

Sur ma machine, il était environ 3 fois plus rapide. La différence est qu'au lieu d'appeler imshow chaque fois que nous rendons, nous venons de changer les données RVB sur la parcelle d'origine.

import gym
from IPython import display
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline

env = gym.make('Breakout-v0')
env.reset()
img = plt.imshow(env.render(mode='rgb_array')) # only call this once
for _ in range(100):
    img.set_data(env.render(mode='rgb_array')) # just update the data
    display.display(plt.gcf())
    display.clear_output(wait=True)
    action = env.action_space.sample()
    env.step(action)

14voto

Van Points 1812

J'ai réussi à exécuter et rendre openai/salle de fitness (même avec mujoco) à distance sur un serveur headless.

# Install and configure X window with virtual screen
sudo apt-get install xserver-xorg libglu1-mesa-dev freeglut3-dev mesa-common-dev libxmu-dev libxi-dev
# Configure the nvidia-x
sudo nvidia-xconfig -a --use-display-device=None --virtual=1280x1024
# Run the virtual screen in the background (:0)
sudo /usr/bin/X :0 &
# We only need to setup the virtual screen once

# Run the program with vitural screen
DISPLAY=:0 <program>

# If you dont want to type `DISPLAY=:0` everytime
export DISPLAY=:0

Utilisation:

DISPLAY=:0 ipython2

Exemple:

import gym
env = gym.make('Ant-v1')
arr = env.render(mode='rgb_array')
print(arr.shape)
# plot or save wherever you want
# plt.imshow(arr) or scipy.misc.imsave('sample.png', arr)

12voto

mdaoust Points 3789

Il y a aussi cette solution à l'aide de pyvirtualdisplay (un Xvfb wrapper). Une chose que j'aime à propos de cette solution est que vous pouvez lancer à partir de l'intérieur de votre script, au lieu d'avoir à envelopper au lancement:

from pyvirtualdisplay import Display
display = Display(visible=0, size=(1400, 900))
display.start()

11voto

I_like_foxes Points 146

Je suis tombé sur moi-même. À l'aide de xvfb comme serveur X en quelque sorte des affrontements avec les pilotes Nvidia. Mais finalement, ce post m'a orienté dans la bonne direction. Xvfb fonctionne sans aucun problème si vous installez le pilote Nvidia avec l' -no-opengl-files option et avec CUDA --no-opengl-libsoption. Si vous savez cela, il doit travailler. Mais comme il m'a fallu un certain temps jusqu'à ce que je compris cela et il me semble que je ne suis pas le seul à rencontrer des problèmes avec xvfb et les pilotes nvidia.

J'ai écrit toutes les mesures nécessaires pour mettre tout en place sur AWS EC2 exemple avec Ubuntu 16.04 LTS ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X