SOC-91 PACE ICE GPU Enrichment — Full Handoff (2026-03-15)
What the pipeline does
SOC-91 enriches ~56,514 deduplicated Dolma3 shards with WebOrganizer labels (topic + format classification) using GPU jobs on Georgia Tech's PACE ICE HPC cluster. The pipeline runs 4 classifiers per document: TopicClassifier, TopicClassifier-NoURL, FormatClassifier, FormatClassifier-NoURL. Output is labels-only Parquet sidecars uploaded to Cloudflare R2.
Architecture:
- A launcher job (
soc91_launcher, sbatch wrapper aroundlaunch_dual.sh) runs on a CPU node and submits GPU enrichment tasks in batches of 5 - Each enrichment task (
soc91_enrich) gets 1 GPU, reads a line from the manifest (~20 shard paths per line), downloads each shard from R2, runs 4 classifiers, uploads Parquet sidecar +.donemarker +.stats.jsonback to R2 - Idempotency: before processing a shard, checks if
.donemarker exists in R2. Safe to resubmit any task - State file:
logs/soc91_enrich/launcher_state_coe-ice.txttracks which manifest line the launcher will submit next. Launcher reads this on restart to resume - Manifest indexing:
enrich_sidecar.pyreads manifest line N viamanifest.read_text().splitlines()[task_id]. TheTASK_OFFSETenv var maps SLURM array indices to manifest line numbers (since SLURM array indices are capped at 1000)
State at handoff (~22:35 EDT 2026-03-15)
- R2 progress: 19,348/56,514 shards done (34.2%)
- Running GPUs: 8 (severely underutilized, down from 144+ earlier in the week)
- Pending jobs: 0 (396 blocked pending jobs were just cancelled)
- Launcher: alive (job 4461161, ~4.1h into 8h walltime), at task 2,372/2,826
- Launcher log shows: it's now submitting again since pending slots were freed. Was stuck repeating
"At cap (404/400 active, 8 running), waiting..."before the cancel
Known problems
Problem 1: Hidden maintenance reservation blocking all pending jobs
- All 396 pending jobs were stuck with reason
ReqNodeNotAvail, Reserved for maintenance - SLURM's
PrivateData = accounts,jobs,reservations,usage,userssetting hides reservation details from non-admin users. We cannot see when maintenance starts/ends or which nodes are affected - Our jobs request
--time=16:00:00(16h walltime). If maintenance starts within 16h, SLURM won't schedule any new jobs because it can't guarantee completion before maintenance begins - Result: pending jobs consume submit slots (QOS limit = 500) but never run
- Key question: would shorter walltime (4h or 8h) allow jobs to schedule? Each GPU processes ~10 shards/hr, so a 4h job can complete its ~20 shards if the GPU is fast enough
Problem 2: Submit slot exhaustion (QOSMaxSubmitJobPerUserLimit = 500)
- QOS
coe-iceallows max 500 submitted jobs (running + pending combined) - 396 dead-weight pending jobs + 8 running = 404 active, leaving almost no room
- Launcher has its own
MAX_ACTIVE=400cap (line 9 oflaunch_dual.sh) and was stuck because active count exceeded it - As running jobs completed, GPU count declined with no replacements: 144 → 138 → 132 → 127 → 122 → 115 → 12 → 8
- Fix applied: cancelled all 396 pending jobs via
scancel -u gmatlin3 --name=soc91_enrich -t PENDING
Problem 3: Shard selection bias (sequential manifest)
- The manifest (
r2_shard_manifest.txt) is alphabetically sorted: 2,826 lines, ~20 shards each - Launcher processes sequentially (task 0, 1, 2...), so all 19,348 completed shards are from
common_crawlsubcategories starting with letters A-S - Zero coverage of:
olmocr_science_pdfs(21,429 shards, 0%),phase2_nonpool(256 shards, 0%), and 7 common_crawl subcategories (software, software_development, sports_and_fitness, transportation, travel_and_tourism, social_life, fashion_and_beauty) - 8 common_crawl subcategories are at 100% while others are at 0%
- Fix built but not deployed:
build_prioritized_manifest.pycreates a new manifest with 7 tiers by category completion rate, shuffled within tiers, skipping 100%-done categories. Dry-run verified: 39,294 remaining shards across ~1,965 lines
Problem 4: Draining/drained nodes
- 6 GPU nodes currently unavailable (4 drained, 1 drained*, 1 draining)
- As running jobs on draining nodes complete, those GPUs become permanently unavailable until maintenance ends
- This causes the steady decline in running GPUs
Resolved misdiagnosis: "Ghost GPU allocations"
- Initially appeared that 89 GPUs on H100/H200 nodes had zero jobs
- Root cause:
PrivateData = jobshides other users' jobs fromsqueue - The allocations were real jobs from other users, not a bug
What was done on 2026-03-15
- Diagnosed the hidden maintenance reservation as root cause (not a misconfiguration on our end)
- Built
manifest_coverage.py— reports per-subcategory completion rates vs R2 - Built
build_prioritized_manifest.py— prioritized manifest with 7 tiers. Dry-run output:- T0: 28,879 shards (0% done, 16 categories including all olmocr + phase2)
- T1: 2,130 shards (0-15% done)
- T2: 5,350 shards (15-35% done)
- T3: 2,176 shards (35-60% done)
- T4: 180 shards (60-80% done)
- T5: 538 shards (80-95% done)
- T6: 41 shards (95-100% done)
- Skipped: 8,130 shards from 100% complete categories
- Cancelled 396 blocked pending jobs to free submit slots
Action items for next session
Test shorter walltime: Submit a single test job with
--time=4:00:00to see if it schedules. If it does, the maintenance window is >4h away and shorter walltimes bypass the scheduling block:ssh pace-ice "cd ~/dev/data-attribution-soc91 && sbatch --qos=coe-ice --time=4:00:00 --array=0-0 scripts/slurm/enrich_sidecar_gpu.sbatch"Check if it goes to RUNNING or PENDING with
squeue -u gmatlin3 -h -t PENDING -o '%i %r'Deploy the prioritized manifest:
ssh pace-ice "cd ~/dev/data-attribution-soc91 && source ~/.r2_credentials && python3 scripts/slurm/build_prioritized_manifest.py"This writes
scripts/slurm/r2_shard_manifest_prioritized.txt. Then update the launcher to use it by either:- Setting
MANIFEST=scripts/slurm/r2_shard_manifest_prioritized.txtin the sbatch environment - Or editing
enrich_sidecar_gpu.sbatchline 102: changeMANIFEST="${MANIFEST:-scripts/slurm/r2_shard_manifest.txt}"to point at the prioritized manifest - Reset the state file:
echo 0 > logs/soc91_enrich/launcher_state_coe-ice.txt
- Setting
Resubmit launcher when the current one expires (~3.9h remaining on job 4461161):
ssh pace-ice "cd ~/dev/data-attribution-soc91 && sbatch --qos=coe-ice --partition=ice-cpu --time=8:00:00 scripts/slurm/launcher.sbatch"If using shorter walltime for GPU jobs, also update
enrich_sidecar_gpu.sbatchline 8 (--time=16:00:00) before resubmittingMonitor GPU recovery: after cancelling pending jobs the launcher should be submitting new tasks. Verify with:
ssh pace-ice "squeue -u gmatlin3 -h --name=soc91_enrich -t RUNNING | wc -l" ssh pace-ice "squeue -u gmatlin3 -h -r --name=soc91_enrich -t PENDING | wc -l" ssh pace-ice "tail -5 ~/dev/data-attribution-soc91/logs/soc91_launcher/4461161.out"Determine maintenance window: try
scontrol show reservation(may return nothing due to PrivateData), check https://pace.gatech.edu for announcements, or email pace-support@oit.gatech.eduR2 completion check:
ssh pace-ice "source ~/.r2_credentials && python3 -c \"import boto3,os;s3=boto3.client('s3',endpoint_url='https://0934ab8e84ac8f4e81decaf3eb121337.r2.cloudflarestorage.com',aws_access_key_id=os.environ['R2_ACCESS_KEY_ID'],aws_secret_access_key=os.environ['R2_SECRET_ACCESS_KEY'],region_name='auto');p=s3.get_paginator('list_objects_v2');d=sum(1 for pg in p.paginate(Bucket='soc127-dedup',Prefix='soc91-labels/') for o in pg.get('Contents',[]) if o['Key'].endswith('.done'));print(f'r2_done={d}/56514 ({d/56514*100:.1f}%)');\""
Key files on cluster (~/dev/data-attribution-soc91/)
| File | Purpose |
|---|---|
scripts/slurm/r2_shard_manifest.txt |
Current manifest (alphabetical, 2,826 lines, 56,514 shards) |
scripts/slurm/r2_shard_manifest_prioritized.txt |
Output of prioritized builder (not yet generated) |
scripts/slurm/build_prioritized_manifest.py |
Builds prioritized manifest from R2 .done state |
scripts/slurm/manifest_coverage.py |
Reports per-subcategory completion rates |
scripts/slurm/launch_dual.sh |
Launcher logic (MAX_ACTIVE=400, BATCH=5, state checkpoint) |
scripts/slurm/launcher.sbatch |
Launcher sbatch wrapper (CPU node, 18h walltime) |
scripts/slurm/enrich_sidecar_gpu.sbatch |
GPU enrichment job (1 GPU, 16h walltime, auto-detects VRAM/dtype) |
scripts/enrich_sidecar.py |
Enrichment worker (reads manifest by task_id, runs 4 classifiers) |
logs/soc91_enrich/launcher_state_coe-ice.txt |
Current state: 2372 (line number in manifest) |
logs/soc91_launcher/4461161.out |
Current launcher log |
Key constants and infrastructure
| Item | Value |
|---|---|
| R2 bucket | soc127-dedup |
| R2 output prefix | soc91-labels/ |
| R2 endpoint | https://0934ab8e84ac8f4e81decaf3eb121337.r2.cloudflarestorage.com |
| R2 credentials | source ~/.r2_credentials on cluster |
| QOS | coe-ice (max submit: 500, max GPUs: 960) |
| SLURM partitions | ice-gpu,coe-gpu,ice-bw-gpu |
| GPU constraint | -C nvidia-gpu (any NVIDIA GPU) |
| Excluded nodes | atl1-1-03-014-16-0 (bad GPU) |
| Username | gmatlin3 |
| Worktree path | ~/dev/data-attribution-soc91 |
| Launcher MAX_ACTIVE | 400 (in launch_dual.sh) |
| Launcher BATCH | 5 tasks per submission |
| GPU job walltime | 16:00:00 (may need reduction) |
| Batch size | Auto-detected by VRAM (128/64/32/16) |
| Classifier max_length | 8192 tokens |
| Dtype | bf16 (auto-downgrades to fp16 for compute capability < 8.0) |
SSH access pattern
All cluster interaction is via ssh pace-ice "command". Each invocation is a fresh login shell. No state persists between calls. The user must have an active SSH control socket (ControlMaster). If SSH times out or hangs, the user needs to re-authenticate in a separate terminal with ssh pace-ice.
Throughput baseline
- Each GPU processes ~10 shards/hr (varies by GPU type and shard size)
- At 144 GPUs:
1,440 shards/hr (39h for remaining 37,166 shards) - At 8 GPUs:
80 shards/hr (464h, not viable) - Target: get GPU count back above 100 by fixing the scheduling issue
Xet Storage Details
- Size:
- 10.6 kB
- Xet hash:
- f3ef86b5ccd1a9dc564e1523a9676989b81ce750090fe2f1c99c837e38d695a5
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.