../_images/banner.png

Getting Started#

Before you start, make sure you have installed MineStudio and its dependencies.

minestudio Install MineStudio

Installation

Note

If you encounter any issues during installation, please open an issue on GitHub.

Welcome to MineStudio! Please follow the tutorial below for installation.

1. Install JDK 8

To ensure that the Simulator runs smoothly, JDK 8 must be installed on your system. We recommend using Conda to manage environments on Linux systems. If you don’t have Conda, you can install it from Miniconda or Anaconda.

# Create a new conda environment (optional, but recommended)
$ conda create -n minestudio python=3.10 -y

# Activate the environment
$ conda activate minestudio

# Install OpenJDK 8
$ conda install --channel=conda-forge openjdk=8 -y

2. Install MineStudio

You can install MineStudio either from GitHub or PyPI.

a. Install from GitHub (for the latest version):

$ pip install git+https://github.com/CraftJarvis/MineStudio.git

b. Install from PyPI (for stable releases):

$ pip install minestudio

3. Install the Rendering Tool

For GPU-accelerated rendering, especially for users with NVIDIA graphics cards, we recommend installing VirtualGL. For other users, or for a simpler setup, Xvfb can be used, which supports CPU rendering (this is generally slower).

Note

Installing rendering tools and managing services typically requires root permissions. Use sudo before commands like apt, dpkg, and service where necessary.

There are two options:

This option uses Xvfb for CPU-based rendering.

$ sudo apt update
$ sudo apt install -y xvfb mesa-utils libegl1-mesa libgl1-mesa-dev libglu1-mesa-dev

This option uses VirtualGL for GPU-accelerated rendering.

Warning

Not all graphics cards and driver setups support VirtualGL seamlessly. If you do not have strict performance requirements or encounter issues, using the Xvfb rendering tool is often easier to install and configure.

3.1. Download VirtualGL and Helper Script:

You need to download the following:

3.2. Install Dependencies and VirtualGL:

$ sudo apt update
$ sudo apt install -y xvfb mesa-utils libegl1-mesa libgl1-mesa-dev libglu1-mesa-dev xauth xterm
$ sudo dpkg -i virtualgl_3.1_amd64.deb
# If dpkg fails due to missing dependencies, run:
$ sudo apt -f install

3.3. Configure VirtualGL:

Shutdown your display manager (e.g., gdm, lightdm). If you are using GDM, the command is:

$ sudo service gdm stop
# Or for LightDM:
# $ sudo service lightdm stop

Run the VirtualGL server configuration script:

$ sudo /opt/VirtualGL/bin/vglserver_config

You will be prompted with several configuration questions. A common configuration sequence might involve:

  1. Choosing option 1 if prompted to select a display manager configuration (e.g., for GDM/LightDM).

  2. Answering subsequent questions. The original guide suggested a sequence like: Yes, No, No, No. These questions typically relate to:

    • Restricting access to VirtualGL to members of the vglusers group (Recommended: Yes. If you choose Yes, add your user to the vglusers group: sudo usermod -a -G vglusers $USER).

    • Restricting framebuffer readback on the 3D X server to members of the vglusers group (Recommended: Yes).

    • Disabling the XTEST extension on the 3D X server (Recommended: No, unless you have specific security reasons and do not require indirect rendering capabilities). The original guide also mentioned “finally enter X”, the meaning of which is unclear. Please ensure you complete all configuration steps as prompted by the script. If unsure about any option, consulting the official VirtualGL documentation or accepting defaults is advisable.

Restart your display manager:

$ sudo service gdm start
# Or for LightDM:
# $ sudo service lightdm start

3.4. Start VirtualGL Server Script: Execute the downloaded vgl_entrypoint.sh script. Make sure it’s executable (chmod +x vgl_entrypoint.sh).

$ bash ./vgl_entrypoint.sh

Warning

You might need to run vgl_entrypoint.sh each time the system restarts.

3.5. Configure Environment Variables: Add these exports to your shell configuration file (e.g., ~/.bashrc, ~/.zshrc) and source it or open a new terminal.

export PATH="${PATH}:/opt/VirtualGL/bin"
export VGL_DISPLAY="egl" # Or try :0, or the appropriate display connected to your NVIDIA GPU
export VGL_REFRESHRATE="60" # Or your monitor's actual refresh rate
export DISPLAY=":1" # This is often used for the virtual X server display

Ensure these variables are set in the terminal where you run MineStudio.

4. Verify by Running the Simulator

Hint

The first time you run the simulator, a script may ask whether to download compiled model assets from Hugging Face. Choose ‘Y’ to proceed.

If you are using Xvfb:

$ python -m minestudio.simulator.entry

If you are using VirtualGL: Ensure the environment variables from step 3.5 are set.

$ MINESTUDIO_GPU_RENDER=1 python -m minestudio.simulator.entry

If you see output similar to the following, the installation is successful:

Speed Test Status:
Average Time: 0.03
Average FPS: 38.46
Total Steps: 50

Speed Test Status:
Average Time: 0.02
Average FPS: 45.08
Total Steps: 100

MineStudio Libraries Quickstart#

Click on the dropdowns for your desired library to get started:

minestudio Simulator: Customizable Minecraft Environment

Here is a minimal example of how to use the simulator:

from minestudio.simulator import MinecraftSim

sim = MinecraftSim(action_type="env")
obs, info = sim.reset()
for _ in range(100):
    action = sim.action_space.sample()
    obs, reward, terminated, truncated, info = sim.step(action)
sim.close()

Also, you can customize the environment by chaining multiple callbacks. Here is an example:

import numpy as np
from minestudio.simulator import MinecraftSim
from minestudio.simulator.callbacks import (
    SpeedTestCallback, 
    RecordCallback, 
    SummonMobsCallback, 
    MaskActionsCallback, 
    RewardsCallback, 
    CommandsCallback, 
    FastResetCallback
)

sim = MinecraftSim(
    action_type="env",
    callbacks=[
        SpeedTestCallback(50), 
        SummonMobsCallback([{'name': 'cow', 'number': 10, 'range_x': [-5, 5], 'range_z': [-5, 5]}]),
        MaskActionsCallback(inventory=0, camera=np.array([0., 0.])), 
        RecordCallback(record_path="./output", fps=30),
        RewardsCallback([{
            'event': 'kill_entity', 
            'objects': ['cow', 'sheep'], 
            'reward': 1.0, 
            'identity': 'kill sheep or cow', 
            'max_reward_times': 5, 
        }]),
        CommandsCallback(commands=[
            '/give @p minecraft:iron_sword 1',
            '/give @p minecraft:diamond 64',
        ]), 
        FastResetCallback(
            biomes=['mountains'],
            random_tp_range=1000,
        )
    ]
)
obs, info = sim.reset()
print(sim.action_space)
for i in range(100):
    action = sim.action_space.sample()
    obs, reward, terminated, truncated, info = sim.step(action)
sim.close()

Learn more about MineStudio Simulator

minestudio Data: Flexible Data Structures and Fast Dataloaders

Here is a minimal example to show how we load trajectories from the dataset.

from minestudio.data import RawDataset
from minestudio.data.minecraft.callbacks import ImageKernelCallback, ActionKernelCallback

dataset = RawDataset(
    dataset_dirs=[
        '/nfs-shared-2/data/contractors/dataset_6xx', 
        '/nfs-shared-2/data/contractors/dataset_7xx', 
        '/nfs-shared-2/data/contractors/dataset_8xx', 
        '/nfs-shared-2/data/contractors/dataset_9xx', 
        '/nfs-shared-2/data/contractors/dataset_10xx', 
    ],
    modal_kernel_callbacks=[
        ImageKernelCallback(frame_width=224, frame_height=224, enable_video_aug=False), 
        ActionKernelCallback(enable_prev_action=True, win_bias=1, read_bias=-1),
    ],
    win_len=128, 
    split_ratio=0.9,
    shuffle_episodes=True,
)
item = dataset[0]
print(item.keys())

You may see the output like this:

[23:09:38] [Kernel] Modal image load 15738 episodes.
[23:09:38] [Kernel] Modal action load 15823 episodes.
[23:09:38] [Kernel] episodes: 15655, frames: 160495936.
[Raw Dataset] Shuffling episodes with seed 0. 
dict_keys(['image', 'image_mask', 'action_mask', 'env_action', 'env_prev_action', 'agent_action', 'agent_prev_action', 'mask', 'text', 'timestamp', 'episode', 'progress'])

Hint

Please note that the dataset_dirs parameter here is a list that can contain multiple dataset directories. In this example, we have loaded five dataset directories.

If an element in the list is one of 6xx, 7xx, 8xx, 9xx, or 10xx, the program will automatically download it from Hugging Face, so please ensure your network connection is stable and you have enough storage space. If an element in the list is a directory like /nfs-shared/data/contractors/dataset_6xx, the program will load data directly from that directory.

We strongly recommend users to manually download the datasets and place them in a local directory, such as /nfs-shared-2/data/contractors/dataset_6xx, to avoid downloading issues.

Learn more about Raw Dataset

Alternatively, you can also load trajectories that have specific events, for example, loading all trajectories that contain the kill entity event.

from minestudio.data import EventDataset
from minestudio.data.minecraft.callbacks import ImageKernelCallback, ActionKernelCallback

dataset = EventDataset(
    dataset_dirs=[
        '/nfs-shared-2/data/contractors/dataset_6xx', 
        '/nfs-shared-2/data/contractors/dataset_7xx', 
        '/nfs-shared-2/data/contractors/dataset_8xx', 
        '/nfs-shared-2/data/contractors/dataset_9xx', 
        '/nfs-shared-2/data/contractors/dataset_10xx', 
    ], 
    modal_kernel_callbacks=[
        ImageKernelCallback(frame_width=224, frame_height=224, enable_video_aug=False), 
        ActionKernelCallback(),
    ],
    win_len=128, 
    split_ratio=0.9, 
    event_regex='minecraft.kill_entity:.*', 
    min_nearby=64,
    max_within=1000,
)
print("length of dataset: ", len(dataset))
item = dataset[0]
print(item.keys())

You may see the output like this:

[23:16:07] [Event Kernel Manager] Number of loaded events: 61
[23:16:07] [Kernel] Modal image load 15738 episodes.
[23:16:07] [Kernel] Modal action load 15823 episodes.
[23:16:07] [Kernel] episodes: 15655, frames: 160495936.
[23:16:07] [Event Dataset] Regex: minecraft.kill_entity:.*, Number of events: 61, number of items: 16835. 
length of dataset: 16835
dict_keys(['image', 'env_action', 'agent_action', 'mask', 'text', 'episode', 'timestamp'])

Learn more about Event Dataset

We also provide a dataloader wrapper to make it easier to use the dataset.

from minestudio.data import RawDataModule
from minestudio.data.minecraft.callbacks import (
    ImageKernelCallback, ActionKernelCallback
)

data_module = RawDataModule(
    data_params=dict(
        dataset_dirs=[
            '/nfs-shared-2/data/contractors/dataset_6xx', 
            '/nfs-shared-2/data/contractors/dataset_7xx', 
            '/nfs-shared-2/data/contractors/dataset_8xx', 
            '/nfs-shared-2/data/contractors/dataset_9xx', 
            '/nfs-shared-2/data/contractors/dataset_10xx', 
        ],
        modal_kernel_callbacks=[
            ImageKernelCallback(frame_width=224, frame_height=224, enable_video_aug=False), 
            ActionKernelCallback(enable_prev_action=True, win_bias=1, read_bias=-1),
        ],
        win_len=128, 
        split_ratio=0.9,
        shuffle_episodes=True,
    ),
    batch_size=3,
    num_workers=8,
    prefetch_factor=None,
    episode_continuous_batch=True,
)
data_module.setup()
loader = data_module.train_dataloader()
for idx, batch in enumerate(loader):
    print(
        "\t".join(
            [f"{a} {b}" for a, b in zip(batch['episode'], batch['progress'])]
        )
    )
    if idx > 10:
        break

You may see the output like this:

[23:21:03] [Kernel] Modal image load 15738 episodes.
[23:21:03] [Kernel] Modal action load 15823 episodes.
[23:21:03] [Kernel] episodes: 15655, frames: 160495936.
[Raw Dataset] Shuffling episodes with seed 0. 
[23:21:03] [Kernel] Modal image load 15738 episodes.
[23:21:03] [Kernel] Modal action load 15823 episodes.
[23:21:03] [Kernel] episodes: 15655, frames: 160495936.
[Raw Dataset] Shuffling episodes with seed 0. 
thirsty-lavender-koala-7552d1728d4d-20220411-092042 0/75        Player63-f153ac423f61-20210723-162533 0/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 0/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 1/75        Player63-f153ac423f61-20210723-162533 1/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 1/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 2/75        Player63-f153ac423f61-20210723-162533 2/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 2/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 3/75        Player63-f153ac423f61-20210723-162533 3/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 3/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 4/75        Player63-f153ac423f61-20210723-162533 4/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 4/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 5/75        Player63-f153ac423f61-20210723-162533 5/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 5/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 6/75        Player63-f153ac423f61-20210723-162533 6/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 6/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 7/75        Player63-f153ac423f61-20210723-162533 7/8       wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 7/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 8/75        Player985-f153ac423f61-20210914-114117 0/23     wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 8/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 9/75        Player985-f153ac423f61-20210914-114117 1/23     wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 9/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 10/75       Player985-f153ac423f61-20210914-114117 2/23     wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 10/88
thirsty-lavender-koala-7552d1728d4d-20220411-092042 11/75       Player985-f153ac423f61-20210914-114117 3/23     wiggy-aquamarine-tapir-c09d137a3840-20220318-024035 11/88
minestudio Models: Policy Template and Baselines

Here is an example that shows how to load and use OpenAI’s VPT policy within the Minecraft environment provided by MineStudio.

from minestudio.simulator import MinecraftSim
from minestudio.simulator.callbacks import RecordCallback
from minestudio.models import load_vpt_policy, VPTPolicy

# Option 1: Load the policy from local model files
# Ensure you have the .model (architecture) and .weights (parameters) files.
policy = load_vpt_policy(
    model_path="/path/to/foundation-model-2x.model", 
    weights_path="/path/to/foundation-model-2x.weights"
).to("cuda") # Move the policy to GPU if available

# Option 2: Load the policy from the Hugging Face Model Hub
# This is a convenient way to get pre-trained models.
# policy = VPTPolicy.from_pretrained("CraftJarvis/MineStudio_VPT.rl_from_early_game_2x").to("cuda")

# Set the policy to evaluation mode. This is important for consistent behavior during inference.
policy.eval()

# Initialize the Minecraft Simulator
# obs_size specifies the resolution of the visual observations.
# callbacks allow for custom actions during the simulation, e.g., recording.
env = MinecraftSim(
    obs_size=(128, 128), 
    callbacks=[RecordCallback(record_path="./output", fps=30, frame_type="pov")]
)

# `memory` stores the recurrent state of the policy (e.g., for RNNs).
# For policies without memory (Markovian), it can be initialized to None.
memory = None 
obs, info = env.reset() # Reset the environment to get the initial observation.

# Simulation loop
for i in range(1200): # Run for 1200 steps
    # Get an action from the policy.
    # `obs`: The current observation from the environment.
    # `memory`: The current recurrent state of the policy.
    # `input_shape='*'`: Indicates that `obs` is a single sample (not a batch or time sequence).
    # The policy handles internal batching/unbatching for its forward pass.
    action, memory = policy.get_action(obs, memory, input_shape='*')
    
    # Apply the action to the environment.
    obs, reward, terminated, truncated, info = env.step(action)
    
    # Check if the episode has ended.
    if terminated or truncated:
        print("Episode finished after {} timesteps".format(i+1))
        break

env.close() # Close the environment when done.

Hint

In this example, if RecordCallback is used, the recorded video will be saved in the ./output directory. The memory variable handles the policy’s recurrent state, and input_shape='*' in get_action is typical for single-instance inference.

minestudio Offline: Pre-Training Policy with Offline Data

Tutorial: Fine-tuning VPT to a Hunter

Fine-tune a VPT policy in MineStudio is really simple.

The following code snippet shows how to finetune a VPT policy to hunt animals in Minecraft using offline data.

  1. Import some dependencies:

    import lightning as L
    from lightning.pytorch.loggers import WandbLogger
    from lightning.pytorch.callbacks import LearningRateMonitor
    # below are MineStudio dependencies
    from minestudio.data import MineDataModule
    from minestudio.offline import MineLightning
    from minestudio.models import load_vpt_policy, VPTPolicy
    from minestudio.offline.mine_callbacks import BehaviorCloneCallback
    from minestudio.offline.lightning_callbacks import SmartCheckpointCallback, SpeedMonitorCallback
    
  2. Configure the policy model and the training process:

    policy = VPTPolicy.from_pretrained("CraftJarvis/MineStudio_VPT.foundation_model_2x")
    mine_lightning = MineLightning(
        mine_policy=policy,
        learning_rate=0.00004,
        warmup_steps=2000,
        weight_decay=0.000181,
        callbacks=[BehaviorCloneCallback(weight=0.01)]
    )
    
  3. Configure the data module that contains all the kill_entity trajectory segments:

    episode_continuous_batch = True
    mine_data = MineDataModule(
        data_params=dict(
            mode='event', 
            dataset_dirs=['10xx'],
            win_len=128,
            frame_width=128,
            frame_height=128,
            event_regex="minecraft.kill_entity:.*",
            bias=16,
            min_nearby=64,
        ),
        batch_size=8,
        num_workers=8,
        prefetch_factor=4,
        split_ratio=0.9, 
        shuffle_episodes=True,
        episode_continuous_batch=episode_continuous_batch,
    )
    

    Warning

    If episode_continuous_batch=True, then the dataloader will automatically use our distributed batch sampler. When configuring the trainer, we need to set use_distributed_sampler=False.

  4. Configure the trainer with your preferred PyTorch Lightning callbacks:

    L.Trainer(
        logger=WandbLogger(project="minestudio-vpt"), 
        devices=8, 
        precision="bf16", 
        strategy='ddp_find_unused_parameters_true', 
        use_distributed_sampler=not episode_continuous_batch, 
        gradient_clip_val=1.0, 
        callbacks=[
            LearningRateMonitor(logging_interval='step'), 
            SpeedMonitorCallback(),
            SmartCheckpointCallback(
                dirpath='./weights', filename='weight-{epoch}-{step}', save_top_k=-1, 
                every_n_train_steps=2000, save_weights_only=True,
            ), 
            SmartCheckpointCallback(
                dirpath='./checkpoints', filename='ckpt-{epoch}-{step}', save_top_k=1, 
                every_n_train_steps=2000+1, save_weights_only=False,
            )
        ]
    ).fit(model=mine_lightning, datamodule=mine_data)
    
minestudio Online: Finetuning Policy via Online Interaction

We provide a simple example in online/run. You can fine-tune VPT to complete the task of killing cows by directly running:

cd online/run
bash run.sh

Specifically, this process includes several important configurations:

Policy Generator

which does not accept parameters and directly returns MinePolicy.As an example:

def policy_generator():
    from minestudio.models.openai_vpt.body import load_openai_policy
    model_path = 'pretrained/foundation-model-2x.model'
    weights_path = 'pretrained/bc-from-early-game-2x.weights'
    policy = load_openai_policy(model_path, weights_path)
    return policy

Environment Generator

which does not accept parameters and directly returns MinePolicy. As an example:

def env_generator():
    from minestudio.simulator import MinecraftSim
    from minestudio.simulator.callbacks import (
        SummonMobsCallback, 
        MaskActionsCallback, 
        RewardsCallback, 
        CommandsCallback, 
        JudgeResetCallback,
        FastResetCallback
    )
    sim = MinecraftSim(
        obs_size=(128, 128), 
        preferred_spawn_biome="plains", 
        action_type = "agent",
        timestep_limit=1000,
        callbacks=[
            SummonMobsCallback([{'name': 'cow', 'number': 10, 'range_x': [-5, 5], 'range_z': [-5, 5]}]),
            MaskActionsCallback(inventory=0), 
            RewardsCallback([{
                'event': 'kill_entity', 
                'objects': ['cow'], 
                'reward': 1.0, 
                'identity': 'chop_tree', 
                'max_reward_times': 30, 
            }]),
            CommandsCallback(commands=[
                '/give @p minecraft:iron_sword 1',
                '/give @p minecraft:diamond 64',
                '/effect @p 5 9999 255 true',
            ]),
            FastResetCallback(
                biomes=['plains'],
                random_tp_range=1000,
            ),
            JudgeResetCallback(600),
        ]
    )
    return sim

Config which provide the hyper-parameters for online training:

online_dict = {
 "trainer_name": "PPOTrainer",
    "detach_rollout_manager": True,
    "rollout_config": {
        "num_rollout_workers": 2,
        "num_gpus_per_worker": 1.0,
        "num_cpus_per_worker": 1,
        "fragment_length": 256,
        "to_send_queue_size": 6,
        "worker_config": {
            "num_envs": 12,
            "batch_size": 6,
            "restart_interval": 3600,  # 1h
            "video_fps": 20,
            "video_output_dir": "output/videos",
        },
        "replay_buffer_config": {
            "max_chunks": 4800,
            "max_reuse": 2,
            "max_staleness": 2,
            "fragments_per_report": 40,
            "fragments_per_chunk": 1,
            "database_config": {
                "path": "output/replay_buffer_cache",
                "num_shards": 8,
            },
        },
        "episode_statistics_config": {},
    },
    "train_config": {
        "num_workers": 2,
        "num_gpus_per_worker": 1.0,
        "num_iterations": 4000,
        "vf_warmup": 0,
        "learning_rate": 0.00002,
        "anneal_lr_linearly": 
        "weight_decay": 0.04,
        "adam_eps": 1e-8,
        "batch_size_per_gpu": 1,
        "batches_per_iteration": 200,
        "gradient_accumulation": 10, 
        "epochs_per_iteration": 1, 
        "context_length": 64,
        "discount": 0.999,
        "gae_lambda": 0.95,
        "ppo_clip": 0.2,
        "clip_vloss": False, 
        "max_grad_norm": 5, 
        "zero_initial_vf": True,
        "ppo_policy_coef": 1.0,
        "ppo_vf_coef": 0.5, 
        "kl_divergence_coef_rho": 0.2,
        "entropy_bonus_coef": 0.0,
        "coef_rho_decay": 0.9995,
        "log_ratio_range": 50,  
        "normalize_advantage_full_batch": True, 
        "use_normalized_vf": True,
        "num_readers": 4,
        "num_cpus_per_reader": 0.1,
        "prefetch_batches": 2,
        "save_interval": 10,
        "keep_interval": 40,
        "record_video_interval": 2,
        "fix_decoder": False,
        "resume": None, 
        "resume_optimizer": True,
        "save_path": "output"
    },

    "logger_config": {
        "project": "minestudio_online",
        "name": "bow_cow"
    },
}

online_config = OmegaConf.create(online_dict)

After preparing all the above content, run:

from minestudio.online.rollout.start_manager import start_rolloutmanager
from minestudio.online.trainer.start_trainer import start_trainer
start_rolloutmanager(policy_generator, env_generator, online_cfg)
start_trainer(policy_generator, env_generator, online_cfg)

to start online training.

We use wandb to log and monitor the progress of the run. The corresponding parameters passed to wandb are in config.logger_config. When save_path is None, the checkpoint will be saved to Ray’s working directory at ~/ray_results.

minestudio Inference: Parallel Inference and Record Demonstrations

Here is a minimal example of how to use the inference framework:

import ray
from minestudio.inference import EpisodePipeline, MineGenerator, InfoBaseFilter

from functools import partial
from minestudio.models import load_vpt_policy
from minestudio.simulator import MinecraftSim

if __name__ == '__main__':
    ray.init()
    env_generator = partial(
        MinecraftSim, 
        obs_size = (128, 128), 
        preferred_spawn_biome = "forest", 
    ) # generate the environment
    agent_generator = lambda: VPTPolicy.from_pretrained("CraftJarvis/MineStudio_VPT.rl_from_early_game_2x") # generate the agent
    worker_kwargs = dict(
        env_generator = env_generator, 
        agent_generator = agent_generator,
        num_max_steps = 12000, # provide the maximum number of steps
        num_episodes = 2, # provide the number of episodes for each worker
        tmpdir = "./output",
        image_media = "h264",
    ) # provide the worker kwargs
    pipeline = EpisodePipeline(
        episode_generator = MineGenerator(
            num_workers = 8, # the number of workers
            num_gpus = 0.25, # the number of gpus
            max_restarts = 3, # the maximum number of restarts for failed workers
            **worker_kwargs, 
        ),
        episode_filter = InfoBaseFilter(
            key = "mine_block",
            regex = "*.log",
            num = 1,
        ), # InfoBaseFilter will label episodes mine more than 1 *.log
    )
    summary = pipeline.run()
    print(summary)
minestudio Benchmark: Benchmarking and Evaluation

Papers#

Our libraries directly support models from the following papers: