Repository: Farama-Foundation/Metaworld
Issue: [Bug Report] gym.make not working for ML1
Root cause: Documentation Deficiency

### Describe the bug

When following the instructions and run `gym.make("Meta-World/ML1-train", env_name="reach-v3")`, it shows the following error:

`gymnasium.error.Error: Meta-World/ML1-train registered but entry_point is not specified`

When checking the related code:

```
for split in ["train", "test"]:
        register(
            id=f"Meta-World/ML1-{split}",
            vector_entry_point=lambda env_name, vector_strategy="sync", autoreset_mode=gym.vector.AutoresetMode.SAME_STEP, total_tasks_per_cls=None, meta_batch_size=20, seed=None, num_envs=None, **kwargs: _ml_bench_vector_entry_point(
                env_name,
                split,  # type: ignore[arg-type]
                vector_strategy,
                autoreset_mode,
                total_tasks_per_cls,
                seed,
                meta_batch_size,
                num_envs,
                **kwargs,
            ),
            kwargs={},
        )
```
only `vector_entry_point`, instead of `entry_point` is specified. I also tried 
`gym.make_vec("Meta-World/ML1-train", env_name="reach-v3")`

with the following error
`AssertionError: Invalid division of subtasks, expected 2 got 3`

Thanks in advance!

### Code example

```shell
import gymnasium as gym
import metaworld

gym.make("Meta-World/ML1-train", env_name="reach-v3")
# gym.make_vec("Meta-World/ML1-train", env_name="reach-v3")
```

### System info

gymnasium == 1.1.1, metaworld == 3.0.0, python == 3.11, installed with pip.
OS: ubuntu 22.04



### Additional context

_No response_

### Checklist

- [x] I have checked that there is no similar [issue](https://github.com/Farama-Foundation/Gymnasium/issues) in the repo


You can try this:

```python
import gymnasium as gym
import metaworld
import numpy as np

env = gym.make("Meta-World/MT1", env_name="push-v3", seed=42)
# env = gym.make_vec('Meta-World/MT10', vector_strategy='sync', seed=42)

observation, info = env.reset()

print(observation)

for _ in range(10):
    action = env.action_space.sample()
    observation, reward, terminated, truncated, info = env.step(action)

env.close()
```


Thanks for the reply. I understand multi-task benchmarks `MT` can run without any issues. I'm having issues with meta-learning benchmarks `ML1-{train, test}`, `ML10-{test}` and `ML45-{train, test}`.

For MetaWorld, MT10/MT50 and ML1/ML10/ML45 instantiations define a benchmark by generating 50 goal vectors per train / test task. For example:
```py
from metaworld import ML10
benchmark = ML10(seed)
# can now access benchmark.train_classes and benchmark.test_classes and benchmark.train_tasks and benchmark.test_tasks
```
where `classes` = the actual distinct tasks, and `tasks` = goal vectors for each class. You can then instantiate the classes with the tasks and manage the training setup or vectorise the environments however you like.

Now, with `gym.make` we provide a lot of the boilerplate for basic MetaWorld setups for you through additional wrappers that get added, and we also automatically instantiate an `AsyncVectorEnv` or `SyncVectorEnv` accordingly as part of this boilerplate to e.g. run the 10 tasks of MT10 or 50 tasks of MT50 in parallel and change their goal vector each env reset. For meta-learning, it gets a bit more complex for a few reasons (e.g. you often don't want to simply sample a new goal vector each reset).

Specifically, by convention, in meta-learning usually you want to sample a "meta-batch" of tasks from the "task space" each meta-train iteration. This is usually reported in meta-reinforcement learning papers as "meta-batch size". In simple meta-rl envs like for example, HalfCheetah-RandomDirec, the "task space" is simply the angle in the direction where there is reward for that task. So one would sample "meta-batch size" different directions each meta-train iteration and put them in a vectorised environment usually.

In MetaWorld, we have two task dimensions: the actual tasks in the train/test set, as well as their goal vectors. Historically people who've done meta-rl on MetaWorld usually consider the task space as the combinatorial task space of every combination of train/test task with its corresponding goal vectors. For ML1, there is only 1 task but 50 goal vectors, so the task space is simply those 50 goal vectors.

For ML10, if we consider a meta-batch size of 10, then we can essentially have a similar vectorised setup as with MT10, where each env in parallel is a distinct task, and each meta-train iteration we just have to sample a new goal vector for each task in this vector env. However, historically people have done meta-batch size of 20. So how can we now have a meta-learning training setup with such a meta-batch size while not sampling the same (task,goal vector) combination potentially? We can have each task twice in the vector env, but split the generated goal vectors down the middle and have each env sample from a distinct subset of 25 goal vectors each meta-train iteration. (Note: for ML45 people usually do meta-batch size of 45, which is simpler to reason about and that's what the gym.make version of ML45 more or less assumes too, meta-batch size < 45 with gym.make isn't really supported for ML45.)

As a consequence: the meta-batch size actually matters when deciding how to vectorise ML1/ML10/ML45. As a result, the `gym.make` interface for MetaWorld, which aims to provide a lot of the vectorisation / task sampling boilerplate for you, requires this as an argument when trying to instantiate ML1/ML10/ML45. Specifically for ML1, you need to specify the meta-batch size and ideally it should be able to divide 50 (e.g. a good one is 5, or 10). So this would work:

```py
gym.make("Meta-World/ML1", env_name="reach-v3", meta_batch_size=10, seed=42)
```

You might also need to specify `total_tasks_per_cls` if your meta_batch_size does not evenly divide the 50 generated goal vectors for each distinct task in the benchmark. What this flag does is it assigns a subset of goal vectors to sample from to each env instance such that `(meta_batch_size / tasks_in_benchmark) * total_tasks_per_cls < 50`. E.g. if you want to do a meta-batch size of 20 for ML1, which does not evenly divide 50, you can do:
```py
gym.make("Meta-World/ML1", env_name="reach-v3", meta_batch_size=20, total_tasks_per_cls=40, seed=42)
```
And you will use 40 of the 50 total generated goal vectors instead. Each env instance will sample from 2 goal locations each meta-train iteration.

Hopefully this provides some intution for it. Arguably a lot of this should have been added to the `gym.make` documentation for MetaWorld as well, so apologies about that. It will be added in the future.

Thank you very much for the clarification!