Instructions to use XXXpilar/Fastfill-test with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use XXXpilar/Fastfill-test with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Download code/fastfill/v2/tests/test_active_objective_distributed.py from XXXpilar/Fastfill-test: direct link, hf CLI and curl.
- Browser
- Download file 5.56 kB
-
https://huggingface.co/XXXpilar/Fastfill-test/resolve/main/code/fastfill/v2/tests/test_active_objective_distributed.py
- Command line
-
hf download hf://XXXpilar/Fastfill-test/code/fastfill/v2/tests/test_active_objective_distributed.py
-
curl -L -o test_active_objective_distributed.py https://huggingface.co/XXXpilar/Fastfill-test/resolve/main/code/fastfill/v2/tests/test_active_objective_distributed.py
5.56 kB
| """Real Accelerator/Gloo entry-point tests with empty ranks and windows.""" | |
| from copy import deepcopy | |
| from datetime import timedelta | |
| import json | |
| import os | |
| from pathlib import Path | |
| import sys | |
| import pytest | |
| import torch | |
| from fastfill.v2.tests.test_active_objective_training import _row, _yaw_config | |
| def _worker(rank, rendezvous, directory, mode): | |
| from torch import distributed as dist | |
| from fastfill.v2 import train | |
| os.environ.update(RANK=str(rank), WORLD_SIZE="2", LOCAL_RANK=str(rank), LOCAL_WORLD_SIZE="2", | |
| OMP_NUM_THREADS="1", MASTER_ADDR="127.0.0.1", MASTER_PORT="29513") | |
| dist.init_process_group("gloo", init_method=rendezvous, rank=rank, world_size=2, | |
| timeout=timedelta(seconds=20)) | |
| patches = pytest.MonkeyPatch() | |
| try: | |
| if sys.platform == "darwin": | |
| # torch 2.13 barrier(device_ids=[...]) chooses the available MPS | |
| # accelerator even for a CPU/Gloo group. This CPU test explicitly | |
| # selects CPU discovery; collectives/backward remain real Gloo. | |
| patches.setattr(torch._C, "_get_accelerator", lambda: torch.device("cpu")) | |
| root = Path(directory) | |
| rows_count = {"peer_empty": 2, "last_empty": 4, "empty_then_valid": 8, "all_empty": 4}[mode] | |
| data = root / "train.jsonl" | |
| if rank == 0: | |
| data.write_text("".join(json.dumps(_row(str(i))) + "\n" for i in range(rows_count))) | |
| dist.barrier() | |
| original_collate, original_preflight, original_loader = train.collate_samples, train._preflight, train.DataLoader | |
| state = {"after_preflight": False} | |
| def collate(rows, *args, **kwargs): | |
| batch = original_collate(rows, *args, **kwargs) | |
| if state["after_preflight"]: | |
| yaw = batch["validity"]["yaw"].clone() | |
| for i, row in enumerate(rows): | |
| identity = int(row["provenance"]["scene_id"]) | |
| empty = (mode == "all_empty" or (mode == "peer_empty" and rank == 0) | |
| or (mode == "last_empty" and identity >= 2) | |
| or (mode == "empty_then_valid" and identity < 4)) | |
| if empty: | |
| yaw[i] = False | |
| batch = {**batch, "validity": {**batch["validity"], "yaw": yaw}} | |
| return batch | |
| def preflight(*args, **kwargs): | |
| state["after_preflight"] = False | |
| result = original_preflight(*args, **kwargs) | |
| state["after_preflight"] = True | |
| return result | |
| def loader(rows, **kwargs): | |
| return original_loader(rows, **{**kwargs, "shuffle": False}) | |
| models, before = [], [] | |
| original_build = train.build_model | |
| def build(config): | |
| model = original_build(config) | |
| models.append(model) | |
| before.append(deepcopy(model.state_dict())) | |
| return model | |
| patches.setattr(train, "collate_samples", collate) | |
| patches.setattr(train, "_preflight", preflight) | |
| patches.setattr(train, "DataLoader", loader) | |
| patches.setattr(train, "build_model", build) | |
| config = _yaw_config() | |
| config["training"]["gradient_accumulation_steps"] = 1 if mode == "peer_empty" else 2 | |
| if mode == "all_empty": | |
| with pytest.raises(RuntimeError, match="no active objective"): | |
| train.run_training(config, data, root / "run") | |
| changed = sum(not torch.equal(before[0][name], value) for name, value in models[0].state_dict().items()) | |
| assert changed == 0 | |
| observation = {"optimizer_updates": 0, "changed_parameter_tensors": changed} | |
| else: | |
| logs = train.run_training(config, data, root / "run") | |
| assert len(logs) == 1 and logs[0]["step"] == 1 | |
| assert logs[0]["active_objective_count"] == {"peer_empty": 1, "last_empty": 2, "empty_then_valid": 4}[mode] | |
| assert logs[0]["gradient_norms"]["yaw_logits_head"] > 0 | |
| changed = sum(not torch.equal(before[0][name], value) for name, value in models[0].state_dict().items()) | |
| assert changed > 0 | |
| observation = {"optimizer_updates": 1, "active_objective_count": logs[0]["active_objective_count"], | |
| "changed_parameter_tensors": changed} | |
| if rank == 0: | |
| manifest = json.loads((root / "run/run_manifest.json").read_text()) | |
| assert manifest["world_size"] == 2 | |
| assert manifest["skipped_no_objective_windows"] == int(mode == "empty_then_valid") | |
| (root / f"rank-{rank}.json").write_text(json.dumps(observation, indent=2) + "\n") | |
| finally: | |
| patches.undo() | |
| if dist.is_initialized(): | |
| dist.destroy_process_group() | |
| def test_actual_two_rank_objective_windows(tmp_path, monkeypatch, mode): | |
| monkeypatch.setenv("GLOO_SOCKET_IFNAME", "lo0" if sys.platform == "darwin" else "lo") | |
| monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "") # CPU Gloo ranks: with one visible GPU, rank 1 would ask for cuda:1 | |
| torch.multiprocessing.spawn(_worker, args=("file://" + str(tmp_path / "rendezvous"), str(tmp_path), mode), | |
| nprocs=2, join=True) | |
| assert all((tmp_path / f"rank-{rank}.json").exists() for rank in range(2)) | |