diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 00000000..f3e71650 --- /dev/null +++ b/.typos.toml @@ -0,0 +1,5 @@ +[default.extend-words] +# numpy / PyTorch array-range function — not a misspelling of "arrange" +arange = "arange" +# "nd" abbreviation (n-dimensional) — not a misspelling of "and" +nd = "nd" diff --git a/config/model/yaak/control_transformer/raw_vjepa.yaml b/config/model/yaak/control_transformer/raw_vjepa.yaml index 70869793..070068b8 100644 --- a/config/model/yaak/control_transformer/raw_vjepa.yaml +++ b/config/model/yaak/control_transformer/raw_vjepa.yaml @@ -379,6 +379,13 @@ objectives: # null is intentional: the speed projection LayerNorms its inputs and # foresight features pass through their own projection norm: null + # AR rollout loss: set ar_steps: 0 (or feedback_projection: null) to disable. + # When disabled the loss dict is unchanged — no structural diff vs the original. + ar_steps: 1 + feedback_projection: + _target_: rmind.components.nn.Linear + in_features: ${image_embedding_dim} + out_features: ${encoder_embedding_dim} patch_pos_embed: _target_: rmind.components.position_encoding.PatchPositionEmbedding2D grid_size: [16, 16] diff --git a/notebooks/ar_sanity_checks.ipynb b/notebooks/ar_sanity_checks.ipynb new file mode 100644 index 00000000..9a514b33 --- /dev/null +++ b/notebooks/ar_sanity_checks.ipynb @@ -0,0 +1,341 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", + "metadata": {}, + "source": [ + "# AR Rollout Loss — Sanity Checks\n", + "\n", + "Two checks:\n", + "1. **Rollout error curve** — L1 error vs prediction step index for TF vs AR.\n", + " A well-trained AR loss should show slower error growth than TF-only.\n", + "3. **Feature distribution overlap** — PCA of predicted vs true patch embeddings.\n", + " AR predictions should cluster closer to the true distribution than TF.\n", + "\n", + "Requires a checkpoint trained with `ar_steps: 1` and a small validation batch." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "acae54e37e7d407bbb7b55eff062a284", + "metadata": {}, + "outputs": [], + "source": "from __future__ import annotations\n\nfrom pathlib import Path\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nfrom einops import repeat\nfrom sklearn.decomposition import PCA\n\nfrom rmind.components.base import Modality\nfrom rmind.components.transformer.decoder import CrossAttentionDecoderHead\nfrom rmind.models.control_transformer import ControlTransformer\n\n# ── user config ────────────────────────────────────────────────────────────────\nCHECKPOINT = Path(\"../checkpoints/ar_rollout/last.ckpt\") # adjust to your path\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nN_BATCHES = 4\n# ───────────────────────────────────────────────────────────────────────────────" + }, + { + "cell_type": "markdown", + "id": "9a63283cbaf04dbcab1f6479b197f3a8", + "metadata": {}, + "source": [ + "## Load model + datamodule" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8dd0d8092fe74a7c96281538738b07e2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "from hydra import compose, initialize_config_dir\n", + "from hydra.utils import instantiate\n", + "\n", + "model = ControlTransformer.load_from_checkpoint(CHECKPOINT, map_location=DEVICE)\n", + "model.eval()\n", + "\n", + "sys.path.insert(0, \"..\")\n", + "with initialize_config_dir(\n", + " config_dir=str(Path(\"../config\").resolve()), version_base=None\n", + "):\n", + " cfg = compose(\n", + " config_name=\"train\",\n", + " overrides=[\n", + " \"+experiment=yaak/control_transformer/pretrain_vjepa\",\n", + " \"data.num_workers=0\",\n", + " \"data.batch_size=2\",\n", + " ],\n", + " )\n", + "\n", + "datamodule = instantiate(cfg.data)\n", + "datamodule.setup(\"validate\")\n", + "val_loader = datamodule.val_dataloader()" + ] + }, + { + "cell_type": "markdown", + "id": "72eea5119410473aa328ad9291626812", + "metadata": {}, + "source": [ + "## Collect TF and AR predictions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8edb47106e1a46a883d545849b8ab81b", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import TYPE_CHECKING, Any, cast\n", + "\n", + "if TYPE_CHECKING:\n", + " from rmind.components.objectives.forward_dynamics import (\n", + " ForwardDynamicsPredictionObjective,\n", + " )\n", + "\n", + "all_tf_preds: list[torch.Tensor] = [] # [B, T-1, N, D]\n", + "all_ar_preds: list[torch.Tensor] = [] # [B, T-2, N, D]\n", + "all_targets: list[torch.Tensor] = [] # [B, T-1, N, D]\n", + "\n", + "objective = cast(\n", + " \"ForwardDynamicsPredictionObjective\", model.objectives[\"forward_dynamics\"]\n", + ")\n", + "foresight_cam = (\"foresight\", \"cam_front_left\")\n", + "\n", + "with torch.no_grad():\n", + " for i, raw_batch in enumerate(val_loader):\n", + " if i >= N_BATCHES:\n", + " break\n", + "\n", + " batch = {\n", + " k: v.to(DEVICE) if isinstance(v, torch.Tensor) else v\n", + " for k, v in raw_batch.items()\n", + " }\n", + " episode = model.episode_builder(batch)\n", + " embedding = model.encoder(\n", + " src=episode.embeddings_unpacked, mask=episode.attention_mask\n", + " )\n", + "\n", + " metrics: Any = objective.compute_metrics(episode=episode, embedding=embedding)\n", + "\n", + " tf_logits: torch.Tensor = metrics[\"_artifacts\"][\"last_embeddings\"][\n", + " Modality.FORESIGHT\n", + " ][\"cam_front_left\"]\n", + " targets: torch.Tensor = metrics[\"_artifacts\"][\"last_targets\"][\n", + " Modality.FORESIGHT\n", + " ][\"cam_front_left\"]\n", + "\n", + " all_tf_preds.append(tf_logits.cpu())\n", + " all_targets.append(targets.cpu())\n", + "\n", + " if objective.ar_steps > 0 and objective.feedback_projection is not None:\n", + " index = episode.index[:-1]\n", + " k = (Modality.SUMMARY, \"action_summary\")\n", + " action_summary = index.select(k).parse(embedding).get(k)\n", + "\n", + " _, _, n_patches, _ = episode.embeddings.get((\n", + " Modality.IMAGE,\n", + " \"cam_front_left\",\n", + " )).shape\n", + " mask_tokens = repeat(\n", + " episode.embeddings.get((Modality.UTILITY, \"mask\"))[:, 1:],\n", + " \"b t 1 d -> b t n d\",\n", + " n=n_patches,\n", + " )\n", + " if objective.patch_pos_embed is not None:\n", + " mask_tokens = objective.patch_pos_embed(mask_tokens)\n", + "\n", + " z_hat_proj = objective.feedback_projection(tf_logits)\n", + " ar_context = torch.cat([z_hat_proj[:, :-1], action_summary[:, 1:]], dim=-2)\n", + " ar_logits = objective.heads.get(foresight_cam)(\n", + " CrossAttentionDecoderHead.Input(\n", + " query=mask_tokens[:, :-1], context=ar_context\n", + " )\n", + " )\n", + " all_ar_preds.append(ar_logits.cpu())" + ] + }, + { + "cell_type": "markdown", + "id": "10185d26023b46108eb7d9f57d49d2b3", + "metadata": {}, + "source": [ + "## Sanity Check 1 — Rollout Error Curve\n", + "\n", + "L1 error per prediction step: TF predicts `z[t+1]` from observed `z[t]`; AR predicts `z[t+2]` from its own prediction `z_hat[t+1]`. Both are conditioned on the true action.\n", + "\n", + "We expect:\n", + "- TF step-1 error is the training loss baseline.\n", + "- AR step-2 error should be lower (or at least not diverge badly) compared to a model trained without the AR loss." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8763a12b2bbd4a93a75aff182afb95dc", + "metadata": {}, + "outputs": [], + "source": [ + "tf_stack = torch.cat(all_tf_preds, dim=0) # [N_total, T-1, n_patches, D]\n", + "tgt_stack = torch.cat(all_targets, dim=0) # [N_total, T-1, n_patches, D]\n", + "\n", + "# TF error per timestep slot (mean over batch, patches, dim)\n", + "tf_err_per_step = (tf_stack - tgt_stack).abs().mean(dim=(0, 2, 3)) # [T-1]\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 4))\n", + "steps = np.arange(1, len(tf_err_per_step) + 1)\n", + "ax.plot(steps, tf_err_per_step.numpy(), marker=\"o\", label=\"TF (step 1 ... T-1)\")\n", + "\n", + "if all_ar_preds:\n", + " ar_stack = torch.cat(all_ar_preds, dim=0) # [N_total, T-2, n_patches, D]\n", + " ar_err_per_step = (ar_stack - tgt_stack[:, 1:]).abs().mean(dim=(0, 2, 3)) # [T-2]\n", + " ar_steps_x = np.arange(2, len(ar_err_per_step) + 2)\n", + " ax.plot(\n", + " ar_steps_x,\n", + " ar_err_per_step.numpy(),\n", + " marker=\"s\",\n", + " linestyle=\"--\",\n", + " label=\"AR (step 2 ... T-1)\",\n", + " )\n", + "\n", + "ax.set_xlabel(\"Prediction step (1 = next frame)\")\n", + "ax.set_ylabel(\"Mean L1 error\")\n", + "ax.set_title(\"Rollout error curve — TF vs AR\")\n", + "ax.legend()\n", + "ax.grid(alpha=0.3)\n", + "plt.tight_layout()\n", + "plt.savefig(\"rollout_error_curve.png\", dpi=150)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "7623eae2785240b9bd12b16a66d81610", + "metadata": {}, + "source": [ + "**What to look for:**\n", + "- The AR curve at step 2 should be *below* what you'd get if you just naively extended the TF step-1 error (i.e. below the TF value at step 2 from a TF-only model).\n", + "- If AR error is *much higher* than TF at the same step, the feedback signal is not helping — revisit `feedback_projection` capacity or learning rate." + ] + }, + { + "cell_type": "markdown", + "id": "7cdc8c89c7104fffa095e18ddfef8986", + "metadata": {}, + "source": [ + "## Sanity Check 3 — Feature Distribution Overlap\n", + "\n", + "PCA of predicted patch embeddings vs ground-truth patch embeddings. \n", + "Good AR predictions should overlap with the true distribution rather than drifting.\n", + "\n", + "We use the first 2 principal components computed on the true embeddings." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b118ea5561624da68c537baed56e602f", + "metadata": {}, + "outputs": [], + "source": [ + "def flatten_step(tensor: torch.Tensor, step_idx: int = 0) -> np.ndarray:\n", + " \"\"\"Extract patches at a given timestep: [B, T, N, D] -> [(B*N), D].\"\"\"\n", + " x = tensor[:, step_idx] # [B, N, D]\n", + " return x.reshape(-1, x.shape[-1]).numpy()\n", + "\n", + "\n", + "true_feats = flatten_step(tgt_stack, step_idx=0)\n", + "tf_feats = flatten_step(tf_stack, step_idx=0)\n", + "\n", + "pca = PCA(n_components=2)\n", + "pca.fit(true_feats)\n", + "\n", + "true_2d = pca.transform(true_feats)\n", + "tf_2d = pca.transform(tf_feats)\n", + "\n", + "n_plots = 2 if all_ar_preds else 1\n", + "fig, axes = plt.subplots(1, n_plots, figsize=(6 * n_plots, 5))\n", + "if n_plots == 1:\n", + " axes = [axes]\n", + "\n", + "\n", + "def scatter_pair(ax: plt.Axes, pred_2d: np.ndarray, label: str, title: str) -> None:\n", + " ax.scatter(*true_2d.T, s=4, alpha=0.3, label=\"true z\", color=\"steelblue\")\n", + " ax.scatter(*pred_2d.T, s=4, alpha=0.3, label=label, color=\"tomato\")\n", + " ax.set_title(title)\n", + " ax.legend(markerscale=3)\n", + " ax.set_xlabel(\"PC1\")\n", + " ax.set_ylabel(\"PC2\")\n", + "\n", + "\n", + "scatter_pair(axes[0], tf_2d, \"TF pred\", \"TF: predicted vs true (step 1)\")\n", + "\n", + "if all_ar_preds:\n", + " ar_stack = torch.cat(all_ar_preds, dim=0)\n", + " ar_feats = flatten_step(ar_stack, step_idx=0)\n", + " true_step2_feats = flatten_step(tgt_stack, step_idx=1)\n", + " true_step2_2d = pca.transform(true_step2_feats)\n", + " ar_2d = pca.transform(ar_feats)\n", + "\n", + " ax2 = axes[1]\n", + " ax2.scatter(*true_step2_2d.T, s=4, alpha=0.3, label=\"true z[2]\", color=\"steelblue\")\n", + " ax2.scatter(*ar_2d.T, s=4, alpha=0.3, label=\"AR pred z[2]\", color=\"tomato\")\n", + " ax2.set_title(\"AR: predicted vs true (step 2)\")\n", + " ax2.legend(markerscale=3)\n", + " ax2.set_xlabel(\"PC1\")\n", + " ax2.set_ylabel(\"PC2\")\n", + "\n", + "plt.suptitle(\"Feature distribution overlap — PCA of patch embeddings\", y=1.01)\n", + "plt.tight_layout()\n", + "plt.savefig(\"feature_distribution.png\", dpi=150)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "938c804e27f84196a10c8828c723f798", + "metadata": {}, + "source": [ + "**What to look for:**\n", + "- TF and AR predicted distributions should visually overlap with the true distribution (not form a separate cluster).\n", + "- If predictions form a tight cluster far from the true distribution, the model is predicting a constant or collapsed mode — check the loss weight and whether the `feedback_projection` has been initialized properly.\n", + "- PCA explains variance; for a quantitative score use average cosine similarity between predicted and nearest true embedding." + ] + }, + { + "cell_type": "markdown", + "id": "504fb2a444614c0babb325280ed9130a", + "metadata": {}, + "source": [ + "## Bonus: mean cosine similarity" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59bbdb311c014d738909a11f9e486628", + "metadata": {}, + "outputs": [], + "source": [ + "true_t = tgt_stack[:, 0].reshape(-1, tgt_stack.shape[-1])\n", + "tf_t = tf_stack[:, 0].reshape(-1, tf_stack.shape[-1])\n", + "\n", + "cos_tf = F.cosine_similarity(tf_t, true_t, dim=-1).mean().item()\n", + "print(f\"TF step-1 mean cosine sim: {cos_tf:.4f}\") # noqa: T201\n", + "\n", + "if all_ar_preds:\n", + " true_t2 = tgt_stack[:, 1].reshape(-1, tgt_stack.shape[-1])\n", + " ar_t2 = torch.cat(all_ar_preds, dim=0)[:, 0].reshape(-1, tgt_stack.shape[-1])\n", + " cos_ar = F.cosine_similarity(ar_t2, true_t2, dim=-1).mean().item()\n", + " print(f\"AR step-2 mean cosine sim: {cos_ar:.4f}\") # noqa: T201" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index c23f2802..4965b73b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ test = ["pytest>=9.0.2", "pytest-lazy-fixtures>=1.4.0"] train = [ "contextily>=1.6.2", "matplotlib>=3.10.3", + "scikit-learn>=1.6", "torchmetrics>=1.9", "wandb>=0.24.2", ] @@ -88,6 +89,7 @@ build-backend = "hatchling.build" DEP001 = ["app", "rmind"] DEP002 = [ "funcy", + "scikit-learn", "torchmetrics", "pytest", "pytest-lazy-fixtures", @@ -98,6 +100,7 @@ DEP003 = ["rmind"] [tool.deptry.package_module_name_map] hydra-core = "hydra" +scikit-learn = "sklearn" tensordict-nightly = "tensordict" pytorch-lightning = [ "pytorch_lightning", diff --git a/src/rmind/components/objectives/forward_dynamics.py b/src/rmind/components/objectives/forward_dynamics.py index a50cebe4..ec9dc99c 100644 --- a/src/rmind/components/objectives/forward_dynamics.py +++ b/src/rmind/components/objectives/forward_dynamics.py @@ -2,7 +2,7 @@ from typing import Any, final, override import torch -from einops import pack, repeat +from einops import pack, rearrange, repeat from einops.layers.torch import Rearrange from pydantic import InstanceOf, validate_call from tensordict import TensorDict @@ -21,6 +21,7 @@ Prediction, Targets, ) +from rmind.components.transformer.decoder import CrossAttentionDecoderHead @final @@ -35,6 +36,8 @@ def __init__( # noqa: PLR0913 targets: Targets | None = None, projections: InstanceOf[ModuleDict] | None = None, patch_pos_embed: InstanceOf[Module] | None = None, + ar_steps: int = 0, + feedback_projection: InstanceOf[Module] | None = None, ) -> None: super().__init__() @@ -44,6 +47,8 @@ def __init__( # noqa: PLR0913 self.targets: Targets | None = targets self.projections: ModuleDict | None = projections self.patch_pos_embed: Module | None = patch_pos_embed + self.ar_steps: int = ar_steps + self.feedback_projection: Module | None = feedback_projection @override def compute_metrics(self, *, episode: Episode, embedding: Tensor) -> Metrics: @@ -97,11 +102,83 @@ def compute_metrics(self, *, episode: Episode, embedding: Tensor) -> Metrics: tree_map(Rearrange("b t s ... -> (b t s) ..."), targets), ) # ty:ignore[call-non-callable] + if ( + self.ar_steps > 0 + and self.feedback_projection is not None + and self.projections is not None + and self.losses is not None + ): + losses = self._ar_losses( + logits=logits, + losses=losses, + action_summary=action_summary, + mask_tokens=mask_tokens, + episode=episode, + ) + return { "loss": losses, "_artifacts": {"last_embeddings": logits, "last_targets": targets}, } + def _ar_losses( + self, + *, + logits: dict, + losses: dict, + action_summary: Tensor, + mask_tokens: Tensor, + episode: Episode, + ) -> dict: + if ( + self.feedback_projection is None + or self.targets is None + or self.losses is None + ): + return losses + + foresight_key = ("foresight", "cam_front_left") + + # z_hat_tf: b (T-1) n_patches image_embedding_dim + z_hat_tf = logits[Modality.FORESIGHT]["cam_front_left"] + t_minus_1 = z_hat_tf.shape[1] + + if t_minus_1 < 2: # noqa: PLR2004 + return losses + + # Project each patch independently (preserves spatial structure): + # b (T-1) n_patches image_embedding_dim → b (T-1) n_patches encoder_embedding_dim + z_hat_proj = self.feedback_projection(z_hat_tf) + + # AR context for predicting z[t+2]: + # use all predicted patches from z_hat[t] + action_summary[t+1] as one extra token + z_hat_ctx_ar = z_hat_proj[:, :-1] # b (T-2) n_patches encoder_embedding_dim + action_summary_ar = action_summary[:, 1:] # b (T-2) 1 encoder_embedding_dim + # b (T-2) (n_patches+1) encoder_embedding_dim — already in decoder dim, skip projections + ar_context = torch.cat([z_hat_ctx_ar, action_summary_ar], dim=-2) + + ar_logits = self.heads.get(foresight_key)( + CrossAttentionDecoderHead.Input( + query=mask_tokens[:, :-1], # b (T-2) n_patches encoder_embedding_dim + context=ar_context, + ) + ) # b (T-2) n_patches image_embedding_dim + + # targets for AR: true embeddings at z[2:] + foresight_target_key = self.targets[Modality.FORESIGHT]["cam_front_left"] + ar_targets = episode.get(foresight_target_key)[:, 2:] + + ar_loss = self.losses.get(foresight_key)( + rearrange(ar_logits, "b t s d -> (b t s) d"), + rearrange(ar_targets, "b t s d -> (b t s) d"), + ) + + # split leaf loss into tf / ar for separate wandb logging + tf_loss = losses[Modality.FORESIGHT]["cam_front_left"] + losses[Modality.FORESIGHT]["cam_front_left"] = {"tf": tf_loss, "ar": ar_loss} + + return losses + @override def predict( self, diff --git a/uv.lock b/uv.lock index a891c51c..eeceb8dd 100644 --- a/uv.lock +++ b/uv.lock @@ -997,8 +997,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "kornia-rs" }, { name = "packaging" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/e6/45e757d4924176e4d4e111e10effaab7db382313243e0188a06805010073/kornia-0.8.2.tar.gz", hash = "sha256:5411b2ce0dd909d1608016308cd68faeef90f88c47f47e8ecd40553fd4d8b937", size = 667151, upload-time = "2025-11-08T12:10:03.042Z" } @@ -1052,8 +1052,8 @@ version = "0.1.22" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "lovely-numpy" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/07/f5/3aacac6994ceef69fbd6adb71432c8b57afb56bd08065b5b942fdc464dda/lovely_tensors-0.1.22.tar.gz", hash = "sha256:712d30313215225cb8c43dcaca99e1e89a5f58480e770c4a6192dd71cc99d591", size = 23973, upload-time = "2026-03-11T23:31:38.904Z" } @@ -2018,8 +2018,8 @@ dependencies = [ { name = "lightning-utilities" }, { name = "packaging" }, { name = "pyyaml" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, { name = "torchmetrics" }, { name = "tqdm" }, @@ -2119,8 +2119,8 @@ dependencies = [ { name = "pydantic" }, { name = "structlog" }, { name = "tensordict" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, { name = "torchdata" }, { name = "tqdm" }, @@ -2244,14 +2244,14 @@ dependencies = [ { name = "structlog" }, { name = "tensordict" }, { name = "timm" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, - { name = "torchaudio", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torchaudio", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torchaudio", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torchaudio", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torchaudio", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, - { name = "torchvision", version = "0.26.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torchvision", version = "0.26.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torchvision", version = "0.26.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torchvision", version = "0.26.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torchvision", version = "0.26.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] @@ -2267,6 +2267,7 @@ test = [ train = [ { name = "contextily" }, { name = "matplotlib" }, + { name = "scikit-learn" }, { name = "torchmetrics" }, { name = "wandb" }, ] @@ -2315,6 +2316,7 @@ requires-dist = [ { name = "pytorch-lightning", specifier = ">=2.6.0" }, { name = "rbyte", extras = ["geo", "jpeg", "yaak"], specifier = "==0.34.6" }, { name = "rbyte", extras = ["visualize"], marker = "extra == 'predict'" }, + { name = "scikit-learn", marker = "extra == 'train'", specifier = ">=1.6" }, { name = "structlog", specifier = ">=25.2.0" }, { name = "tensordict", specifier = "==0.11.0" }, { name = "timm", specifier = ">=1.0.22" }, @@ -2401,6 +2403,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" }, ] +[[package]] +name = "scikit-learn" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/74/e6a7cc4b820e95cc38cf36cd74d5aa2b42e8ffc2d21fe5a9a9c45c1c7630/scikit_learn-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e", size = 8548242, upload-time = "2025-12-10T07:07:51.568Z" }, + { url = "https://files.pythonhosted.org/packages/49/d8/9be608c6024d021041c7f0b3928d4749a706f4e2c3832bbede4fb4f58c95/scikit_learn-1.8.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76", size = 8079075, upload-time = "2025-12-10T07:07:53.697Z" }, + { url = "https://files.pythonhosted.org/packages/dd/47/f187b4636ff80cc63f21cd40b7b2d177134acaa10f6bb73746130ee8c2e5/scikit_learn-1.8.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4", size = 8660492, upload-time = "2025-12-10T07:07:55.574Z" }, + { url = "https://files.pythonhosted.org/packages/97/74/b7a304feb2b49df9fafa9382d4d09061a96ee9a9449a7cbea7988dda0828/scikit_learn-1.8.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a", size = 8931904, upload-time = "2025-12-10T07:07:57.666Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c4/0ab22726a04ede56f689476b760f98f8f46607caecff993017ac1b64aa5d/scikit_learn-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:35c007dedb2ffe38fe3ee7d201ebac4a2deccd2408e8621d53067733e3c74809", size = 8019359, upload-time = "2025-12-10T07:07:59.838Z" }, + { url = "https://files.pythonhosted.org/packages/24/90/344a67811cfd561d7335c1b96ca21455e7e472d281c3c279c4d3f2300236/scikit_learn-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:8c497fff237d7b4e07e9ef1a640887fa4fb765647f86fbe00f969ff6280ce2bb", size = 7641898, upload-time = "2025-12-10T07:08:01.36Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, + { url = "https://files.pythonhosted.org/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017, upload-time = "2026-02-23T00:18:21.502Z" }, + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682, upload-time = "2026-02-23T00:19:07.67Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340, upload-time = "2026-02-23T00:19:12.024Z" }, +] + [[package]] name = "sentry-sdk" version = "2.59.0" @@ -2513,8 +2556,8 @@ dependencies = [ { name = "orjson" }, { name = "packaging" }, { name = "pyvers" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] wheels = [ @@ -2524,6 +2567,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/fc/659137f50d77fe868614963f322bfb47a1cd7ff685b3a34f00ffcd78d04f/tensordict-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:d62f24c4dbf5e0eed1231beeb482e5b183d2fcb9c9e199828506f5eec5ad8a86", size = 510247, upload-time = "2026-01-26T11:36:12.118Z" }, ] +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + [[package]] name = "timm" version = "1.0.27" @@ -2532,11 +2584,11 @@ dependencies = [ { name = "huggingface-hub" }, { name = "pyyaml" }, { name = "safetensors" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, - { name = "torchvision", version = "0.26.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torchvision", version = "0.26.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torchvision", version = "0.26.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torchvision", version = "0.26.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torchvision", version = "0.26.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/54/ece85b0eef3700c90db8271a43669b05a0ebbe2edb1962329c34374a297e/timm-1.0.27.tar.gz", hash = "sha256:315dfe63186ca9fb7ff941268941231fd5be259f2b4bb4afa28560ae1015cb9a", size = 2439861, upload-time = "2026-05-08T19:38:36.844Z" } @@ -2568,16 +2620,15 @@ version = "2.11.0" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform == 'darwin'", - "platform_machine == 's390x' and sys_platform == 'darwin'", ] dependencies = [ - { name = "filelock", marker = "sys_platform == 'darwin'" }, - { name = "fsspec", marker = "sys_platform == 'darwin'" }, - { name = "jinja2", marker = "sys_platform == 'darwin'" }, - { name = "networkx", marker = "sys_platform == 'darwin'" }, - { name = "setuptools", marker = "sys_platform == 'darwin'" }, - { name = "sympy", marker = "sys_platform == 'darwin'" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin'" }, + { name = "filelock", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "fsspec", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "jinja2", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "networkx", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "setuptools", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "sympy", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "typing-extensions", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:43b35116802c85fb88d99f4a396b8bd4472bfca1dd82e69499e5a4f9b8b4e252", upload-time = "2026-03-23T15:16:58Z" }, @@ -2590,15 +2641,16 @@ source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", + "platform_machine == 's390x' and sys_platform == 'darwin'", ] dependencies = [ - { name = "filelock", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "fsspec", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "jinja2", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "networkx", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "setuptools", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "sympy", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "typing-extensions", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "filelock", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "fsspec", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "jinja2", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "networkx", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "setuptools", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "sympy", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "typing-extensions", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp312-cp312-win_amd64.whl", hash = "sha256:1abeaa46fa7532ed35ed79146f4de5d7a9d4b30462c98052ea4ddfe781ea3eca", upload-time = "2026-04-28T00:06:34Z" }, @@ -2651,7 +2703,6 @@ version = "2.11.0" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform == 'darwin'", - "platform_machine == 's390x' and sys_platform == 'darwin'", ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torchaudio-2.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1cf1acc883bee9cb906a933572fed6a8a933f86ef34e9ea7d803f72317e8c1b", upload-time = "2026-03-23T15:50:10Z" }, @@ -2664,6 +2715,7 @@ source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", + "platform_machine == 's390x' and sys_platform == 'darwin'", ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torchaudio-2.11.0%2Bcpu-cp312-cp312-win_amd64.whl", hash = "sha256:95d517bd1a0a28dacd1c37550ced95cab64f3a7a4ef9b8219b41049388a71163", upload-time = "2026-03-23T15:50:10Z" }, @@ -2688,8 +2740,8 @@ version = "0.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, { name = "urllib3" }, ] @@ -2705,8 +2757,8 @@ dependencies = [ { name = "lightning-utilities" }, { name = "numpy" }, { name = "packaging" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/81/34/39b8b749333db56c0585d7a11fa62a283c087bb1dfc897d69fb8cedbefb1/torchmetrics-1.9.0.tar.gz", hash = "sha256:a488609948600df52d3db4fcdab02e62aab2a85ef34da67037dc3e65b8512faa", size = 581765, upload-time = "2026-03-09T17:41:22.443Z" } @@ -2720,12 +2772,11 @@ version = "0.26.0" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform == 'darwin'", - "platform_machine == 's390x' and sys_platform == 'darwin'", ] dependencies = [ - { name = "numpy", marker = "sys_platform == 'darwin'" }, - { name = "pillow", marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, + { name = "numpy", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "pillow", marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, + { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine != 's390x' and sys_platform == 'darwin'" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torchvision-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c409e1c3fdebec7a3834465086dbda8bf7680eff79abf7fd2f10c6b59520a7a4", upload-time = "2026-03-23T15:36:09Z" }, @@ -2738,11 +2789,12 @@ source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "platform_machine != 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", "platform_machine == 's390x' and sys_platform != 'darwin' and sys_platform != 'linux'", + "platform_machine == 's390x' and sys_platform == 'darwin'", ] dependencies = [ - { name = "numpy", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "pillow", marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin' and sys_platform != 'linux'" }, + { name = "numpy", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "pillow", marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 's390x' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://download-r2.pytorch.org/whl/cpu/torchvision-0.26.0%2Bcpu-cp312-cp312-win_amd64.whl", hash = "sha256:52aa8401850a9792e71a8a1e65ac004e2b23622a6b6fd278cd11179efbefc65b", upload-time = "2026-03-23T15:36:09Z" },