# EB-JEPA learns embeddings by predicting representations, not pixels

> EB-JEPA is an Apache-2.0 library from Meta AI Research that ships three self-contained JEPA examples for images, video and action conditioned planning, each trained with a single GPU and a uv managed environment.

**facebookresearch/eb_jepa** — An open source library designed to provide community examples of Joint Embedding Predictive Architectures (JEPAs). It contains code and examples for learning representations from images, video, and action-conditioned video, as well as planning using JEPA-based models.

- Repository: https://github.com/facebookresearch/eb_jepa
- Stars: 796 · Forks: 108
- Language: Python
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/facebookresearch-eb-jepa

## Predicting embeddings instead of reconstructing pixels

EB-JEPA is an open source library and tutorial for learning representations used for prediction and planning with joint embedding predictive architectures, published by Meta AI Research, FAIR. The name expands to Energy-Based Joint-Embedding Predictive Architectures. The defining idea of a JEPA is that the model learns in embedding space rather than in pixel space. Instead of asking a network to reconstruct the next frame of a video, which pushes it to spend capacity on detail nobody downstream cares about, a JEPA is trained to predict the representation of a future or masked region given the representation of what it can see. The practical payoff is that the learned embeddings are meant to be consumed by something else, such as a planner, rather than by a human looking at pictures. The library ships the training code and the examples together, and the documentation makes a point of scale: each example is nearly self contained, and training takes up to a few hours on a single GPU card. That makes it a research project you can actually run, not just read.

## Three examples that build on each other

The repository is organised around three example projects, each in its own directory under examples. The Image JEPA example learns self-supervised representations from unlabeled images on CIFAR-10 and evaluates them on classification, which gives you a numeric check on whether the embeddings carry useful information. The Video JEPA example changes the prediction target to the next image representation in a sequence, with Moving MNIST as the demonstration. The AC Video JEPA example goes further and adds action conditioning, so the model becomes a world model used for planning in the Two Rooms environment, where an episode is defined as moving from an initial state to a goal state. That progression from static images, to sequences, to action conditioned prediction is the best way to understand what the library is doing, because each example adds one idea rather than changing the whole architecture. The library itself lives in the eb_jepa package, with the examples importing from it, and the packaging configuration includes only eb_jepa and its subpackages, so the training scripts are separate from the shipped code.

## uv sync, or conda plus uv for the awkward dependencies

Package management is done with uv, and the quick path is short:

```bash
# Install dependencies
uv sync
# Option 1: Activate virtual environment
source .venv/bin/activate
python main.py
# Option 2: Run directly with uv
uv run python main.py
```

If some dependencies only exist in conda, the documentation gives a combined route that creates a conda environment first and then lets uv install the package in editable mode with its dev group, which brings pytest, black and isort:

```bash
# Create conda environment with Python 3.12
conda create -n eb_jepa python=3.12 -y
conda activate eb_jepa
# Install package in editable mode with dev dependencies (pytest, black, isort)
uv pip install -e . --group dev
```

Two environment variables matter, and the documentation asks you to put them in your shell profile. EBJEPA_DSETS points at the dataset directory, and it is required so that SLURM jobs can find data on a cluster. EBJEPA_CKPTS points at the directory for checkpoints and logs and is optional:

```bash
# Required for SLURM jobs to find datasets
export EBJEPA_DSETS=/path/to/eb_jepa/datasets
# Optional: Directory for checkpoints and logs
export EBJEPA_CKPTS=/path/to/checkpoints
```

The manifest pins the interpreter hard. requires-python is set to ==3.12.*, and the declared dependencies include torch 2.6.0, torchvision, torchcodec, gymnasium, wandb with media support, submitit, decord, pymunk, omegaconf and scikit-learn, which tells you the project expects a recent Python and a real GPU stack rather than a minimal install.

## Training one example on a single card

Training an example is a module invocation, and the three example names are interchangeable:

```bash
# Local training
python -m examples.{image_jepa,video_jepa,ac_video_jepa}.main
```

A Makefile wraps the same calls for convenience, with one target per example:

```bash
run_image_jepa: ## Run the image JEPA example
	uv run python examples/image_jepa/main.py
```

The hardware expectation is the first real constraint and the documentation is direct about it. The default configs are tuned for H100 GPUs, and on older cards such as A100 or V100 you may need to reduce the batch size to fit in memory. That single sentence is the difference between a run that starts and a run that dies with an out of memory error, so treat the batch size as the first knob to touch. The documentation also states that training takes up to a few hours on a single GPU, which is a meaningful commitment for a three seed sweep. Results land in a unified checkpoints folder where each example has its own directory, and single local runs are marked with a dev prefix and timestamp while sweeps get a sweep prefix, so a run written on 2026-01-16 at midnight and ten seconds is distinguishable from an automatic three seed sweep launched at the same moment.

## Sweeps through SLURM, with seeds grouped in wandb

Experiments scale through a SLURM launcher script, examples/launch_sbatch.py, whose flags cover the choice of example, a config path, a single job, a custom sweep name, an array parallelism limit, a full hyperparameter sweep and the wandb sweep interface. A single job looks like this:

```bash
# Single job
python -m examples.launch_sbatch --example image_jepa --fname examples/image_jepa/cfgs/default.yaml --single
```

The distinction that matters is between a three seed sweep and a full sweep. Without the full-sweep flag the launcher only starts the three seed sweep, which runs the same hyperparameters with different seeds. The full-sweep flag instead reads a sweep.param_grid section from the example YAML config, and the documentation shows the shape of that section, which is where you decide what actually varies:

```yaml
# Example: examples/image_jepa/cfgs/default.yaml
sweep:
  param_grid:
    loss.cov_coeff: [0.1, 1.0, 10.0, 100.0]
    loss.std_coeff: [1.0, 10.0]
    meta.seed: [1, 1000, 10000]
```

Seed averaging is handled in the wandb interface: runs with identical hyperparameters but different seeds share a run name, and you group by name in the runs table to average them, then filter by group to isolate one sweep. Cluster specific settings such as partition, account and memory live in a SLURM_DEFAULTS dictionary at the top of the launcher, so they are edited in code rather than in a config file.

## Apache-2.0 terms and an early version number

The repository is published under the Apache-2.0 licence and the project metadata names version 0.1.1. That version number is worth reading carefully, because it sets the expectation: this is a library and tutorial released alongside research work, with community examples as the stated purpose, not a product with a compatibility promise. The repository carries a LICENSE.md file, a Makefile, a tests directory and a docs folder, and the documentation states that any library added to eb_jepa must have its own test cases. There are no GitHub releases, so version tracking happens through the manifest and the repository history. The last push was on 2026-07-17, and the paper behind the work is listed as arXiv 2602.03604 with an architecture diagram under docs, so the code and the write-up sit side by side. The dependency set is also worth a second look before you install: torch 2.6.0 is pinned exactly, and video work pulls in decord and torchcodec, so the environment is heavier than a typical Python research package.

## Conclusion

Adopt EB-JEPA if you want to read and modify a working JEPA implementation rather than a paper, and if you have a single modern GPU and a few hours per run. Do not adopt it expecting a production library, since the package version is 0.1.1 and the project describes itself as a set of community examples. Before you start, confirm that your GPU fits the default configs, which the documentation says are tuned for H100 cards, that Python is exactly 3.12 because the manifest pins that version, and that the datasets you point EBJEPA_DSETS at match the environment the example expects.

## FAQ

### How do I set up the EB-JEPA environment?

The project uses uv, so uv sync creates the environment and you can either activate .venv and run python main.py or use uv run python main.py directly. For conda-only dependencies, create a conda environment with Python 3.12 and then run uv pip install -e . --group dev. The manifest pins requires-python to ==3.12.*.

### What GPU do I need to train the EB-JEPA examples?

The documentation states that the default configs are tuned for H100 GPUs, and that on older cards such as A100 or V100 you may need to reduce the batch size to fit in memory. Training takes up to a few hours on a single GPU card.

### What is the difference between the image, video and AC video EB-JEPA examples?

The image example learns self-supervised representations from unlabeled CIFAR-10 images and evaluates them on classification. The video example predicts the next image representation in a sequence. The AC video example adds action conditioning for world modelling and planning in the Two Rooms environment.

### How do I run a hyperparameter sweep in EB-JEPA?

The SLURM launcher examples/launch_sbatch.py accepts flags such as --example, --fname, --single, --sweep, --array-parallelism, --full-sweep and --use-wandb-sweep. Only a three seed sweep runs unless you pass --full-sweep, which reads the sweep.param_grid section of the example YAML config.

## Sources

- [facebookresearch/eb_jepa on GitHub](https://github.com/facebookresearch/eb_jepa)
- [Issues](https://github.com/facebookresearch/eb_jepa/issues)
- [License: Apache-2.0](https://github.com/facebookresearch/eb_jepa/blob/main/LICENSE)
- [README](https://github.com/facebookresearch/eb_jepa/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/facebookresearch-eb-jepa
