Recently, I was trying to reproduce the result and get a feeling about how those diffusion-based reinforcement learning algorithm actually works. It has been a long time I haven’t running RL stuff, and surprisingly found that it is a bit difficult to get it correct at the first time. In this post, I summarized the getting start guide of mujoco-py, debugging tips, and list the errors I have encountered before.
Before using mujoco-py
Mujoco was originally from Roboti and bought by DeepMind. Originally, OpenAI maintains mujoco-py
package until version 2.1.2.14. After that, mujoco-py
was deprecated and DeepMind manages another package called mujoco
. Both packages are available on PyPI.
mujoco-py
was deprecated around 2021, so a lot of works built before 2022 or 2022 are still using the old mujoco-py
package.
Mujoco main program
Notably, mujoco-py
does not contain the main simulation program. Therefore, we need to install the main program before installing mujoco-py
to avoid issues. Here is some handy code snippets to install the main program:
sudo apt install zip -y
cd ~
wget https://www.roboti.us/download/mujoco200_linux.zip
wget https://www.roboti.us/file/mjkey.txt
unzip mujoco200_linux.zip
mkdir ~/.mujoco
mv mjkey.txt ~/.mujoco/mjkey.txt
mv mujoco200_linux ~/.mujoco/mujoco200
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/.mujoco/mujoco200/bin
Mujoco OpenGL dependencies
Moreover, mujoco depends on OpenGL. Therefore, some libraries are required: (Reference)
sudo apt install libosmesa6-dev libgl1-mesa-glx libglfw3
If you don’t have sudo privilege, you may consider using: (Reference).
conda install -c conda-forge mesalib glew glfw
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH
Debugging tips
-
If
environment.yml
contains pip’s packages, extract the pip’s dependencies to another filerequirements.txt
. Because once you have created a conda environment, even if pip failed, you will need to delete the conda environment and restart again. Therefore, it is better to decouple the process to two stage: one is installing conda dependencies, and another is installing pip dependencies. -
Mujoco requires some compiling which is perhaps unfamiliar to people without prior experiences with C development. There are some tips:
-
To compile a C program, its dependencies are usually in the format of
.so
file (shared object)..so
file are reusable so multiple projects can use the same set of.so
files. Those.so
files are used by linker. More importantly, to search for extra.so
files, the linker would see all the paths inLD_LIBRARY_PATH
environmental variable. -
ldconfig -p
: this command shows all.so
files that the linker can see now. If some-lXX
does not work, you can use it to see what does the linker sees. For example, you would like to check whether libGL exists, just useldconfig -p | grep libGL
. -
If your
.so
file does not include in the predefined path, for example, if you install some.so
via Conda, you can useexport LD_LIBRARY_PATH=$CONDA_PREFIX/lib$:LD_LIBRARY_PATH
to let the linker know.
-
-
Conda and pip: There are several packages that can be installed via Conda or Pip. It is very important that one don’t use they in a mixed way. They by default will be installed to the same location. Otherwise, the outcome would be quite unpredictable. An example is that if you already let pip resolve Cython 3 for mujoco-py, the solution is to delete the whole conda env first, put a old version cython in Conda’s dependency, and reinstall the environment again.
-
Rent an instance from a cloud gpu provider to make sure that the fix is reasonable and can be reproduced from a clean setup.
-
Should I use OpenGL installed OS-wide or Conda-wide? I did have a look into this issue. My take is that if you have sudo privilege, use system-wide installation because of two reasons. First, there are multiple implementations for OpenGL (i.e. Nvidia also has its OpenGL drivers), so use one that with hard accelearation is better realisticly. Secondly, Conda-wide installation requires more tweaking, for example, it by default does not provide the symlink of
libGL.so
(Reference: https://github.com/conda-forge/mesalib-feedstock/issues/16), so one have to figure it out manually.
Common Issues
Lack of MESA: fatal error: GL/osmesa.h: No such file or directory
Error Message:
/lib/python3.8/site-packages/mujoco_py/gl/osmesashim.c:1:10: fatal
error: GL/osmesa.h: No such file or directory
1 | #include <GL/osmesa.h>
Solution:
-
It is likely that you don’t have OpenGL mesa installed.
-
See Mujoco OpenGL dependencies for instruction.
Lack of libGL.so
Error messsage:
cannot find -lGL: No such file or directory
Solution:
-
It is likely that you don’t have
libGL.so
while gcc requires this to compile mujoco. -
To check whether you have
libGL.so
, runldconfig -p | grep libGL
and see if there is an exact match likelibGL.so (libc6,x86-64) => /lib/x86_64-linux-gnu/ligGL.so
. (it is notlibGL.so.1
!) Alternatively, you could rungcc -v -lGL
to see if anything changes. -
See Mujoco OpenGL dependencies for instruction. (Note: libGL.so is provided in
libgl1-mesa-dev
package.)
Cython issue: Cannot assign type 'void (const char
) except * nogil' to 'void (
)(const char *) noexcept nogil'.
Error message:
Error compiling Cython file:
------------------------------------------------------------
...
See c_warning_callback, which is the C wrapper to the user defined function
'''
global py_warning_callback
global mju_user_warning
py_warning_callback = warn
mju_user_warning = c_warning_callback
^
------------------------------------------------------------
/workspace/miniconda3/envs/diffuser/lib/python3.8/site-packages/mujoco_py/cymj.pyx:92:23: Cannot assign type 'void (const char *) except * nogil' to 'void (*)(const char *) noexcept nogil'. Exception values are incompatible. Suggest adding 'noexcept' to the type of 'c_warning_callback'.
Error compiling Cython file:
------------------------------------------------------------
...
See c_warning_callback, which is the C wrapper to the user defined function
'''
global py_error_callback
global mju_user_error
py_error_callback = err_callback
mju_user_error = c_error_callback
^
-----------------------
Solution:
-
mujoco-py does not work well with Cython >= 3. To avoid the package manager (pip) resolves the Cython >= 3 version, we must install a old version of Cython first. This can be achieved by adding
cython=0.29.36
to Conda’s dependency list inenvironment.yml
. -
As you can see from the pip install log, it uses incorrect version:
Legacy gym: Unknown distribution option: 'tests_require’
Error message:
Preparing metadata (setup. py) ... error error: subprocess-exited-with-error
x python setup.py egg_info did not run successfully.
exit code: 1
13 lines of outputi
warnings.warn(msg)
[end of output]
/workspace/miniconda3/envs/diffuser/lib/python3.8/site-packages/setuptools/_distutils/dist.py:261: UserWarning: Unknown distribution option: 'tests_require'
error in gym setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
× Encountered error while generating package metadata.
See above for output.
Also,
has invalid metadata: Expected end or semicolon (after version specifier) opencv-python>=3.
Please use pip<24.1 if you need to use this version
Solution:
-
Do not use the latest
setuptools
andwheel
packages. -
Moreover, we must use pip <= 24.0 because legacy specifier has been deprecated. There is a invalid specifier
opencv-python>=3.
in the dependencies. -
In conda’s
environment.yml
, you may use the following in the dependencies list:- pip == 24.0 - setuptools == 63.2.0 - wheel == 0.38.4
Mesa target issue
Error message:
ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by /tmp2/yqkqknct/miniconda3/envs/diffuser/bin/../lib/libOSMesa.so.8)
Solution:
-
It is likely that the libOSMesa used is not what we expected. This happens if you use Conda to install mesalib and the conda environment is not specified in LD_LIBRARY_PATH env variable.
-
Run
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH
to ensure that the mesalib can be found by the linker. -
Reference: https://github.com/pybind/pybind11/discussions/3453