<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Francisco Booth</title>
    <description>The latest articles on DEV Community by Francisco Booth (@franciscobooth).</description>
    <link>https://dev.to/franciscobooth</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4112135%2F6cf0defa-ee9f-417b-9c92-b614563226c8.jpg</url>
      <title>DEV Community: Francisco Booth</title>
      <link>https://dev.to/franciscobooth</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/franciscobooth"/>
    <language>en</language>
    <item>
      <title>“No space left on device” on RunPod: What Causes It and How to Fix It Before Billing Starts</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Tue, 10 Nov 2026 16:21:32 +0000</pubDate>
      <link>https://dev.to/franciscobooth/no-space-left-on-device-on-runpod-what-causes-it-and-how-to-fix-it-before-billing-starts-55d8</link>
      <guid>https://dev.to/franciscobooth/no-space-left-on-device-on-runpod-what-causes-it-and-how-to-fix-it-before-billing-starts-55d8</guid>
      <description>&lt;p&gt;You rent a GPU on RunPod, download your model, start fine-tuning. Everything looks fine until the job crashes:&lt;/p&gt;

&lt;p&gt;OSError: [Errno 28] No space left on device&lt;/p&gt;

&lt;p&gt;Or your training completes but GGUF export fails:&lt;/p&gt;

&lt;p&gt;RuntimeError: [Errno 28] No space left on device&lt;/p&gt;

&lt;p&gt;You have spent money on GPU compute, potentially hours of training, and now you cannot finish the job.&lt;/p&gt;

&lt;p&gt;Having a large storage volume attached does not mean every process is using it. Here is why it happens, how to diagnose it, and how to catch it before the next run starts billing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why RunPod pods run out of disk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RunPod pods have two storage layers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45o77pj50i7prgtg3pm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45o77pj50i7prgtg3pm6.png" alt=" " width="527" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Container disk (/): Fast, small (typically 10–20GB on standard templates), wiped when the pod stops.&lt;/p&gt;

&lt;p&gt;Network volume (/workspace): Persistent, sized by you when you create it.&lt;/p&gt;

&lt;p&gt;The problem is that several things write to container disk by default even when a network volume is attached:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HuggingFace model cache (~/.cache/huggingface unless HF_HOME is set)&lt;/li&gt;
&lt;li&gt;Training checkpoints (most frameworks default to ./output)&lt;/li&gt;
&lt;li&gt;pip cache (~/.cache/pip)&lt;/li&gt;
&lt;li&gt;GGUF export artifacts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any one of these is manageable. Combined on a 10–20GB container disk, they fill it fast.&lt;/p&gt;

&lt;p&gt;Find out which filesystem is actually full first&lt;/p&gt;

&lt;p&gt;Before changing any configuration, identify where space is being consumed:&lt;/p&gt;




&lt;p&gt;df -h&lt;/p&gt;




&lt;p&gt;Look at / and /workspace separately. If / is almost full but /workspace has space, you have a configuration problem not a capacity problem.&lt;/p&gt;

&lt;p&gt;To find what is consuming space on the root filesystem:&lt;/p&gt;




&lt;p&gt;du -xhd1 / 2&amp;gt;/dev/null | sort -h&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The GGUF export case&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GGUF export is the peak disk moment in a typical fine-tuning pipeline. For a 12B model you briefly hold simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The 16-bit merged model (~24GB)&lt;/li&gt;
&lt;li&gt;The f16 GGUF (~24GB)&lt;/li&gt;
&lt;li&gt;The quantised output (~6GB)&lt;/li&gt;
&lt;li&gt;Additional temporary working files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined peak can exceed 50GB. The exact amount depends on your conversion workflow, quantisation method, and whether intermediate files coexist. If your working directory only has 20GB free, the export fails partway through. Hours of training wasted.&lt;/p&gt;

&lt;p&gt;One operator running a Gemma 12B fine-tune on Vast.ai hit exactly this training ran clean for hours, the GGUF export step failed because the working directory had ~20GB against a ~45–47GB peak requirement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three things to set before every job&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Point HF_HOME at the network volume&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;export HF_HOME=/workspace/.cache/huggingface&lt;br&gt;
mkdir -p $HF_HOME&lt;/p&gt;




&lt;p&gt;Add this to your pod startup script, not just your shell profile if training launches via SSH or an automated script it will not load .bashrc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Point your output directory at the network volume&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Hugging Face Trainer
&lt;/h1&gt;

&lt;p&gt;training_args = TrainingArguments(&lt;br&gt;
    output_dir="/workspace/outputs",&lt;br&gt;
    save_total_limit=2,  # prevents old checkpoints filling the volume&lt;br&gt;
)&lt;/p&gt;

&lt;h1&gt;
  
  
  Axolotl
&lt;/h1&gt;

&lt;p&gt;output_dir: /workspace/outputs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Size your volume for the full pipeline, not just training&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Account for base model weights, checkpoints, and export artifacts simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7B model: at least 60GB&lt;/li&gt;
&lt;li&gt;12B model: at least 100GB&lt;/li&gt;
&lt;li&gt;70B model: at least 350GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Catch it before billing starts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;uvx computefence doctor&lt;/p&gt;

&lt;p&gt;Real output from a RunPod A40 pod that caught a disk warning before launch:&lt;/p&gt;

&lt;p&gt;ComputeFence v0.3.2 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/p&gt;

&lt;p&gt;3 WARNINGS  ·  0 BLOCKERS  ·  5 PASSED&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ✓ HF_HOME is set to /workspace/.cache/huggingface&lt;br&gt;
  ✓ Persistent volume(s) detected: /workspace&lt;br&gt;
  ⚠ Volume /workspace — 9.8 GB free of 10.0 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffkd9fp0y6ozbuvsynovd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffkd9fp0y6ozbuvsynovd.png" alt=" " width="598" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9.8GB free on a 10GB volume. The HF_HOME was correctly set. The volume was mounted. But the available capacity was too low for a full training run. Caught before the job started.&lt;/p&gt;

&lt;p&gt;ComputeFence warns below 20GB and blocks below 5GB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current limitation:&lt;/strong&gt; ComputeFence does not yet calculate peak storage requirements from your model size. It checks available capacity and cache configuration. That is a narrower claim than “your pipeline will fit” but it catches the cases where you are obviously going to run out before you start paying.&lt;/p&gt;

&lt;p&gt;Make the check automatic:&lt;/p&gt;




&lt;p&gt;alias train="uvx computefence doctor &amp;amp;&amp;amp; python train.py"&lt;/p&gt;




&lt;p&gt;If disk is below 5GB, ComputeFence exits with a non-zero code and the training command does not run.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>runpod</category>
      <category>gpu</category>
    </item>
    <item>
      <title>“no kernel image is available for execution on the device” What This PyTorch Error Means On RunPod Blackwell GPUs</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Mon, 09 Nov 2026 13:12:16 +0000</pubDate>
      <link>https://dev.to/franciscobooth/no-kernel-image-is-available-for-execution-on-the-device-what-this-pytorch-error-means-on-runpod-4528</link>
      <guid>https://dev.to/franciscobooth/no-kernel-image-is-available-for-execution-on-the-device-what-this-pytorch-error-means-on-runpod-4528</guid>
      <description>&lt;p&gt;You launch a training job on RunPod. PyTorch detects your GPU, torch.cuda.is_available() returns True, and your environment checks appear to pass.&lt;/p&gt;

&lt;p&gt;Then your script reaches its first real CUDA operation and crashes:&lt;/p&gt;




&lt;p&gt;RuntimeError: CUDA error: no kernel image is available for execution on the device&lt;/p&gt;




&lt;p&gt;If you are running on a Blackwell GPU with an older PyTorch build, you have hit a GPU architecture compatibility problem. The frustrating part is that your environment looks perfectly healthy right up until the first CUDA kernel executes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What causes this error&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CUDA kernels are compiled for specific GPU architectures, identified by compute capability for example sm_86 for an A40, sm_90 for an H100.&lt;/p&gt;

&lt;p&gt;When you install PyTorch, the build you download contains kernels compiled for a fixed range of architectures. PyTorch 2.4.1+cu124 supports sm_50 through sm_90.&lt;/p&gt;

&lt;p&gt;Blackwell GPUs: the RTX PRO 4000, RTX PRO 4500, RTX PRO 6000, and RTX 5090 have compute capability sm_120. They are outside that range.&lt;/p&gt;

&lt;p&gt;With an incompatible PyTorch build, PyTorch does not fail immediately. torch.cuda.is_available() returns True. The GPU name appears in the output. Everything looks fine. Then the training script reaches the first real CUDA kernel call the first matrix multiplication, the first forward pass and it throws the error above.&lt;/p&gt;

&lt;p&gt;By that point the pod is already allocated, your dependencies are installed, and billing has started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note on the B200&lt;/strong&gt;: The B200 belongs to the sm_100 architecture family, not sm_120. Always check the actual compute capability reported by your GPU rather than assuming every Blackwell card uses the same architecture.&lt;/p&gt;

&lt;p&gt;You can check this in two lines:&lt;/p&gt;




&lt;p&gt;import torch&lt;br&gt;
cap = torch.cuda.get_device_capability(0)&lt;br&gt;
print(f"Device capability: sm_{cap[0]}{cap[1]}")&lt;br&gt;
print(f"Supported architectures: {torch.cuda.get_arch_list()}")&lt;/p&gt;




&lt;p&gt;If your device capability is not in the supported list, the run will fail when the first kernel executes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why torch.cuda.is_available() returning True is not enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the problem becomes deceptive.&lt;/p&gt;

&lt;p&gt;torch.cuda.is_available() confirms that PyTorch can access CUDA and identify a device. It does not confirm that the installed build contains compatible kernels for every operation you intend to run. Architecture compatibility is a separate check.&lt;/p&gt;

&lt;p&gt;GPU detection and GPU compatibility are two different things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First-hand reproduction on RunPod&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I reproduced this on a RunPod RTX PRO 4000 Blackwell pod using the default PyTorch 2.4.1+cu124 template.&lt;/p&gt;

&lt;p&gt;The terminal output looked clean:&lt;/p&gt;




&lt;p&gt;✓ PyTorch 2.4.1+cu124 detected (CUDA available — NVIDIA RTX PRO 4000 Blackwell)&lt;/p&gt;




&lt;p&gt;Meanwhile PyTorch was printing a warning to stderr that sm_120 was not supported by this build. The pre-flight check passed. Training would have failed on the first real kernel call.&lt;/p&gt;

&lt;p&gt;The warning that appeared in stderr:&lt;/p&gt;




&lt;p&gt;UserWarning: CUDA device capability sm_120 is not supported by this PyTorch build.&lt;br&gt;
Supported capabilities: sm_50 through sm_90.&lt;/p&gt;




&lt;p&gt;If your training script runs in a tmux session, pipes output to a log file, or uses a framework like Axolotl or Unsloth, you will miss this warning entirely until the forward pass crashes.&lt;/p&gt;

&lt;p&gt;The pod also reported /workspace - 466126.9 GB free of 2190892.5 GB unusually large volume figures that appear to be a virtualisation reporting artefact on early Blackwell deployments rather than real capacity.&lt;/p&gt;

&lt;p&gt;This reproduction exposed a gap in the original pre-flight checks and led directly to the GPU architecture check added in ComputeFence v0.3.2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which GPUs are affected with standard PyTorch images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As of PyTorch 2.4.x, these cards are not supported by the builds shipped in standard RunPod PyTorch templates:&lt;/p&gt;

&lt;p&gt;NVIDIA RTX PRO 4000 Blackwell: sm_120&lt;br&gt;
NVIDIA RTX PRO 4500 Blackwell: sm_120&lt;br&gt;
NVIDIA RTX PRO 6000 Blackwell: sm_120&lt;br&gt;
NVIDIA RTX 5090: sm_120&lt;br&gt;
NVIDIA B200: sm_100 (different architecture, same class of problem)&lt;/p&gt;

&lt;p&gt;If RunPod assigns one of these GPUs and you are on the default template, you will hit this error on the first kernel call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How ComputeFence catches it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since v0.3.2, ComputeFence compares each GPU’s compute capability against the architectures supported by the installed PyTorch build using get_device_capability() and get_arch_list(). A mismatch is flagged as a blocker not a warning:&lt;/p&gt;




&lt;p&gt;✗ BLOCKER: GPU architecture mismatch&lt;br&gt;
  NVIDIA RTX PRO 4000 Blackwell has compute capability sm_120&lt;br&gt;
  This PyTorch build supports sm_50 through sm_90&lt;br&gt;
  Training will fail on the first CUDA kernel call&lt;br&gt;
  Fix: Use a PyTorch build compiled for sm_120, or select a different GPU&lt;/p&gt;




&lt;p&gt;This runs before billing starts.&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;Note: get_arch_list() reports architectures compiled into the PyTorch installation. It is a useful compatibility signal but does not guarantee that every third-party CUDA extension will work. Run a small representative CUDA operation before committing to a long training run on new hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Install a PyTorch build that supports your GPU&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use a release compiled for sm_120. Check pytorch.org/get-started/locally for current compatibility. After installing, verify with the two-line check above before launching your job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Select a different GPU&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you need to use an existing PyTorch image with pinned dependencies, select a GPU whose architecture is in the supported range. An A40 (sm_86) or H100 (sm_90) will work with PyTorch 2.4.x.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The broader lesson&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GPU detection is not GPU compatibility. As providers add newer hardware generations, the gap between the latest cards and the PyTorch builds in standard templates will keep appearing. Passing torch.cuda.is_available() is not proof that your training workload can execute.&lt;/p&gt;

&lt;p&gt;Check the architecture before billing starts.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>runpod</category>
      <category>gpu</category>
    </item>
    <item>
      <title>Your RunPod Checkpoints Disappeared When The Pod Stopped. Here Is Why.</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Sun, 08 Nov 2026 18:56:29 +0000</pubDate>
      <link>https://dev.to/franciscobooth/your-runpod-checkpoints-disappeared-when-the-pod-stopped-here-is-why-4j54</link>
      <guid>https://dev.to/franciscobooth/your-runpod-checkpoints-disappeared-when-the-pod-stopped-here-is-why-4j54</guid>
      <description>&lt;p&gt;You ran a training job. It completed. You stopped the pod to save money. You came back and the checkpoints were gone.&lt;/p&gt;

&lt;p&gt;No error. No warning. Just an empty directory where the weights should be.&lt;/p&gt;

&lt;p&gt;This is one of the most common failures in rented GPU compute and it is entirely preventable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the checkpoints disappeared&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RunPod pods have two kinds of storage:&lt;/p&gt;

&lt;p&gt;Container storage: The root filesystem (/, /root, /tmp, /home). Fast. Exists only while the pod is running. When you stop or terminate the pod, everything on container storage is wiped. This is ephemeral storage.&lt;/p&gt;

&lt;p&gt;Network volume: Mounted at /workspace when you attach one. Persists across pod stops and restarts. Costs a small amount per GB per month but survives when the pod does not.&lt;/p&gt;

&lt;p&gt;Most training frameworks default to writing checkpoints to container storage. Hugging Face Trainer defaults to ./output. Axolotl defaults to a path under the working directory. Stop the pod and those files are gone.&lt;/p&gt;

&lt;p&gt;One important distinction: stopping a pod and terminating a pod behave differently depending on your RunPod configuration. Spot instances can be terminated abruptly. For safety, treat container storage as temporary regardless of pod lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The paths that disappear&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your checkpoint output directory resolves to any of these, the weights will not survive pod termination:&lt;/p&gt;




&lt;p&gt;/root/...&lt;br&gt;
/home/...&lt;br&gt;
/tmp/...&lt;br&gt;
./output          — resolves to container storage&lt;br&gt;
~/.cache/...&lt;/p&gt;




&lt;p&gt;If the path is under /workspace, it survives provided /workspace is backed by a network volume you have attached.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two separate settings. Both must be fixed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the detail that causes most repeat failures. There are two independent configuration settings that both default to ephemeral storage. Fixing one does not fix the other.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkpoint output directory&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;python&lt;br&gt;
-# Hugging Face Trainer&lt;br&gt;
training_args = TrainingArguments(&lt;br&gt;
    output_dir="/workspace/outputs",&lt;br&gt;
    ...&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;yaml&lt;br&gt;
-# Axolotl&lt;br&gt;
output_dir: /workspace/outputs&lt;/p&gt;




&lt;p&gt;Not ./output. Not /root/outputs. Explicitly /workspace/outputs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HuggingFace cache&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Base model weights download to HF_HOME. If it is unset, they go to ~/.cache/huggingface — container storage. When the pod stops, every model shard you downloaded is gone and must be downloaded again.&lt;/p&gt;




&lt;p&gt;bash&lt;br&gt;
export HF_HOME=/workspace/.cache/huggingface&lt;/p&gt;

&lt;p&gt;Add this to your pod startup script so it runs before Python starts. If your training launches via SSH or an automated script, set it inside the launch script itself rather than relying on .bashrc:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
-#!/usr/bin/env bash&lt;br&gt;
export HF_HOME=/workspace/.cache/huggingface&lt;br&gt;
python train.py&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why this keeps happening&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Training frameworks assume a permanent local filesystem. Cloud GPU providers assume the developer knows how storage works. Between them sits an unmonitored gap.&lt;/p&gt;

&lt;p&gt;During eight structured user research sessions with ML engineers, checkpoint loss to ephemeral storage was the most consistently reported failure. The majority had experienced it. In most cases there was no error the job completed successfully and the weights simply were not there afterwards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Catch it before the job starts&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;bash&lt;br&gt;
uvx computefence doctor&lt;/p&gt;




&lt;p&gt;Real output from a RunPod A40 pod running v0.3.2 — this session had HF_HOME correctly set, so storage passed. The disk warning on /workspace is real and would have caused a checkpoint failure mid-run:&lt;/p&gt;




&lt;p&gt;ComputeFence v0.3.2 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/p&gt;

&lt;p&gt;3 WARNINGS  ·  0 BLOCKERS  ·  5 PASSED&lt;/p&gt;

&lt;p&gt;Environment&lt;br&gt;
  ✓ Python 3.11.10&lt;br&gt;
  ✓ PyTorch 2.4.1+cu124 detected (CUDA available — NVIDIA A40)&lt;br&gt;
  ✓ NVIDIA A40 compute capability sm_86 is supported by this PyTorch build&lt;br&gt;
  ⚠ No Accelerate config found — skipping GPU count check&lt;br&gt;
    Fix: Run 'accelerate config' to create a configuration file&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ✓ HF_HOME is set to /workspace/.cache/huggingface&lt;br&gt;
  ✓ Persistent volume(s) detected: /workspace&lt;br&gt;
  ⚠ Volume /workspace — 9.8 GB free of 10.0 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;/p&gt;

&lt;p&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
3 warning(s) found. Review before launching.&lt;br&gt;
Exit codes: 0 = all passed, 1 = warnings, 2 = blockers&lt;/p&gt;




&lt;p&gt;9.8 GB free on a 10 GB volume. A 7B model checkpoint alone would have filled it. Caught before billing started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before your next training job checklist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Network volume is attached and mounted at /workspace&lt;br&gt;
HF_HOME is set to /workspace/.cache/huggingface&lt;br&gt;
output_dir is set to /workspace/outputs or equivalent&lt;br&gt;
Run uvx computefence doctor to verify before billing starts&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>mlops</category>
      <category>runpod</category>
    </item>
    <item>
      <title>I Ran Eight User Research Sessions With ML Engineers About GPU Training Failures. Here Is What They Had In Common.</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Sat, 07 Nov 2026 21:08:25 +0000</pubDate>
      <link>https://dev.to/franciscobooth/i-ran-eight-user-research-sessions-with-ml-engineers-about-gpu-training-failures-here-is-what-they-3f64</link>
      <guid>https://dev.to/franciscobooth/i-ran-eight-user-research-sessions-with-ml-engineers-about-gpu-training-failures-here-is-what-they-3f64</guid>
      <description>&lt;p&gt;The most expensive failure in machine learning infrastructure is not a crash. A crash throws an exception, halts the container, and stops the billing meter.&lt;/p&gt;

&lt;p&gt;The most expensive failure is a job that succeeds at doing the wrong thing.&lt;/p&gt;

&lt;p&gt;Before building ComputeFence I ran eight structured research sessions with ML engineers running fine-tuning workloads on rented GPU compute RunPod, Vast.ai, Lambda Labs. I asked what had gone wrong, what it cost, and whether they saw an error message.&lt;/p&gt;

&lt;p&gt;The pattern was consistent enough that I stopped being surprised after the third session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Checkpoints lost to ephemeral storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The majority of engineers I spoke to had lost model weights because their checkpoint output directory was writing to container storage instead of a persistent volume.&lt;/p&gt;

&lt;p&gt;On providers like RunPod and Vast.ai, storage is partitioned:&lt;/p&gt;

&lt;p&gt;Ephemeral container root (/root, /tmp) is wiped the moment a pod terminates&lt;br&gt;
Persistent network storage lives on dedicated paths like /workspace&lt;/p&gt;

&lt;p&gt;Default training scripts routinely dump checkpoints to ./output or ~/.cache. The job runs for eight hours, logs a clean exit, terminates the pod. The weights are gone.&lt;/p&gt;

&lt;p&gt;The fix is one line set --output_dir /workspace/checkpoints but training harnesses assume the filesystem is permanent, and nothing tells you otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Silent garbage and false convergence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most had also run a job that finished without errors but produced a model that scored at random chance or far below expectations.&lt;/p&gt;

&lt;p&gt;The causes varied:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Duplicate rows poisoning low-rank adapter updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conflicting labels introducing contradictory supervision.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Class weight misconfiguration causing binary classification loss to collapse to 0.693 immediately the exact value of ln(2), which is what you get when a model predicts the majority class for every example.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the outside, the terminal logged steady iterations, GPU utilisation sat at 98%, and loss ticked down slightly. The failure only revealed itself during post-training evaluation after the compute was spent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No error message for any of it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was the consistent thread across every session. The expensive failures were not loud crashes. They were silent completions that only revealed themselves when the model was evaluated.&lt;/p&gt;

&lt;p&gt;One engineer described it as: “The job succeeded at doing the wrong thing.”&lt;/p&gt;

&lt;p&gt;Training frameworks assume the local environment has been provisioned correctly. The cloud GPU host assumes the developer knows what they are doing. Between them sits an unmonitored gap and that gap is where the money goes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The enterprise version of the same problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One session stood out. An engineer at a major industrial company described how their ML team maintains a five to six part manual bash script that they run before every GPU job. Environment checks, storage checks, dependency checks all hand-rolled and maintained internally.&lt;/p&gt;

&lt;p&gt;The reason: no standardised tool exists for this. Every team either builds its own pre-flight script or skips it and pays the cost when something fails silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the sessions changed about ComputeFence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before the research I was focused on CUDA CPU fallback the failure I had hit personally. 24 seconds per iteration instead of 0.4. Training on CPU for hours at full GPU rates. No warning.&lt;/p&gt;

&lt;p&gt;After eight sessions I understood that the most common failure was not the GPU check. It was storage.&lt;/p&gt;

&lt;p&gt;HF_HOME pointing to ephemeral disk. Checkpoint directory writing to container storage. Disk filling up during export. These failures are quieter than a CUDA mismatch and more expensive because they surface at the end of a long run, not the beginning.&lt;/p&gt;

&lt;p&gt;The storage checks became the first thing ComputeFence runs. GPU visibility is second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 30-second pre-flight check&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;uvx computefence doctor&lt;/p&gt;

&lt;p&gt;In order of how commonly the failures appeared across the eight sessions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HuggingFace cache path: Flags if HF_HOME is unset or pointing to ephemeral storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checkpoint output directory: Flags output paths under known ephemeral prefixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disk headroom: Warns below 20GB, blocks below 5GB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GPU and CUDA visibility: Fails if torch.cuda.is_available() returns False.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accelerate configuration: Flags mismatches between configured process count and visible GPUs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dataset integrity: Optional scan for duplicates and conflicting labels with --dataset.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every warning prints the exact fix command. The check takes under 30 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rule of cloud compute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A job that crashes on line one is cheap fix the error and rerun.&lt;/p&gt;

&lt;p&gt;A job that crashes after six hours because the disk filled up on checkpoint four is expensive.&lt;/p&gt;

&lt;p&gt;A job that runs for twelve hours, reports exit code 0, and saves its weights to ephemeral storage is the most expensive of all.&lt;/p&gt;

&lt;p&gt;Pre-flight checks cannot verify model quality or guarantee convergence. They catch the entirely preventable configuration errors that are visible before python train.py. That is a narrower claim than “prevent all failures” but it is an honest one.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>mlops</category>
      <category>gpu</category>
    </item>
    <item>
      <title>Your GGUF Export Will Fail At The End. The Disk Was Never Going To Be Enough.</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Fri, 06 Nov 2026 15:41:53 +0000</pubDate>
      <link>https://dev.to/franciscobooth/your-gguf-export-will-fail-at-the-end-the-disk-was-never-going-to-be-enough-30mc</link>
      <guid>https://dev.to/franciscobooth/your-gguf-export-will-fail-at-the-end-the-disk-was-never-going-to-be-enough-30mc</guid>
      <description>&lt;p&gt;Training finishes clean. The LoRA adapter saved. You kick off the GGUF export.&lt;/p&gt;

&lt;p&gt;Then it dies.&lt;/p&gt;

&lt;p&gt;No space left on device.&lt;/p&gt;

&lt;p&gt;The frustrating part is that nothing warned you. The training job ran for hours without a single disk error. The problem only appeared at the worst possible moment the final step, after all the compute was spent.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why export kills jobs that training survived&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During fine-tuning the disk footprint stays small. You are writing a LoRA adapter and periodic checkpoints a few hundred megabytes at most. The base model weights stay in memory, not on disk.&lt;/p&gt;

&lt;p&gt;GGUF export is different. To convert a fine-tuned model you briefly hold multiple large files simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The 16-bit merged model&lt;/li&gt;
&lt;li&gt;The f16 GGUF&lt;/li&gt;
&lt;li&gt;The quantised outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a 12B model that peak sits at approximately 45–47GB. If your working directory only has 20GB free, the export fails partway through. The merge is incomplete. The GGUF is corrupted or missing.&lt;/p&gt;

&lt;p&gt;A Vast.ai operator described this exactly: training ran clean, disk footprint stayed small, then GGUF export failed because the working directory had ~20GB against a ~45–47GB peak requirement. Silent end-of-pipeline failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this is hard to see before it happens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The disk check that matters for export is different from the disk check that matters for training. During training you need headroom for checkpoints a few GB. During export you need headroom for the full model merge plus conversion artifacts simultaneously.&lt;/p&gt;

&lt;p&gt;Most pre-flight thinking is focused on training. Export is an afterthought.&lt;/p&gt;

&lt;p&gt;There is no error before the job starts. The disk looks fine. Training looks fine. The failure only surfaces at the conversion step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The check before you start&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before any run that ends in GGUF export, check how much space the export will actually need.&lt;/p&gt;

&lt;p&gt;Rough estimate for a model of size N billion parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16-bit merge: approximately 2 × N GB&lt;/li&gt;
&lt;li&gt;f16 GGUF: approximately 2 × N GB&lt;/li&gt;
&lt;li&gt;Quantised output (Q4): approximately 0.5 × N GB&lt;/li&gt;
&lt;li&gt;Peak simultaneous: approximately 4–4.5 × N GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a 12B model that is 48–54GB. For a 7B model that is 28–32GB.&lt;/p&gt;

&lt;p&gt;If your working directory does not have that headroom before the job starts, the export will fail.&lt;/p&gt;




&lt;p&gt;-# Check available disk on your working volume&lt;br&gt;
df -h /workspace&lt;/p&gt;

&lt;p&gt;-# Check total size of base model weights&lt;br&gt;
du -sh /workspace/.cache/huggingface/&lt;/p&gt;




&lt;p&gt;Or run a full environment check in 30 seconds:&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;Real output from a RunPod A40 pod (v0.2.11 — current version is v0.3.1):&lt;/p&gt;




&lt;p&gt;ComputeFence v0.2.11 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/p&gt;

&lt;p&gt;4 WARNINGS  ·  0 BLOCKERS  ·  4 PASSED&lt;/p&gt;

&lt;p&gt;Environment&lt;br&gt;
  ✓ Python 3.12.3&lt;br&gt;
  ✓ PyTorch 2.8.0+cu128 detected (CUDA available — NVIDIA A40)&lt;br&gt;
  ⚠ No Accelerate config found — skipping GPU count check&lt;br&gt;
    Fix: Run 'accelerate config' to create a configuration file&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ✓ HF_HOME is set to /workspace/.cache/huggingface/&lt;br&gt;
  ✓ Persistent volume(s) detected: /workspace&lt;br&gt;
  ⚠ Volume /workspace — 6.0 GB free of 9.3 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;br&gt;
  ⚠ Root disk (/) — 16.2 GB free of 20.0 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;/p&gt;

&lt;p&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
4 warning(s) found. Review before launching.&lt;/p&gt;




&lt;p&gt;That disk warning 6GB free on a 9.3GB volume would catch you before you start a 12B export that needs 45–47GB. The job would not even begin with that headroom. That is the point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three options before any export job:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1 — Attach a larger volume&lt;/strong&gt;&lt;br&gt;
Size it to at least 4–5× your model’s parameter count in GB. For a 12B model that means at least 60GB free before you start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2 — Export in stages&lt;/strong&gt;&lt;br&gt;
Merge first, check disk, then convert. Do not run the full pipeline in a single script if you are not certain about headroom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 3 — Export locally or on cheaper compute&lt;/strong&gt;&lt;br&gt;
GGUF conversion does not need a GPU. Run it on a CPU instance with large cheap disk rather than holding a GPU pod open for the conversion step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What ComputeFence catches today&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ComputeFence checks disk headroom on both the workspace volume and the root disk before launch. It warns below 20GB and blocks below 5GB.&lt;/p&gt;

&lt;p&gt;It does not yet estimate the full GGUF export peak requirement from your model size. That check is on the roadmap. For now the disk warning is the signal if you are below 20GB free before training starts, you will almost certainly be below what export needs at the end.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>mlops</category>
      <category>runpod</category>
    </item>
    <item>
      <title>Why Your Training Script Will Fail on the Next GPU Pod Even If It Worked Last Time</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Mon, 26 Oct 2026 17:45:11 +0000</pubDate>
      <link>https://dev.to/franciscobooth/why-your-training-script-will-fail-on-the-next-gpu-pod-even-if-it-worked-last-time-33eg</link>
      <guid>https://dev.to/franciscobooth/why-your-training-script-will-fail-on-the-next-gpu-pod-even-if-it-worked-last-time-33eg</guid>
      <description>&lt;p&gt;You ran a training job last week. It completed cleanly. Today you rent a fresh pod, run the same script, and something breaks sometimes silently.&lt;/p&gt;

&lt;p&gt;Same script. &lt;/p&gt;

&lt;p&gt;Same model. &lt;/p&gt;

&lt;p&gt;Different pod. &lt;/p&gt;

&lt;p&gt;Different result.&lt;/p&gt;

&lt;p&gt;This is environment drift and it is one of the most expensive, least documented failure modes in rented GPU compute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The myth of the standard pod&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you rent a GPU on RunPod or Vast.ai you are not spinning up a standardised environment. You are renting whatever machine a host made available, layered with a base image that varies by provider, instance type, and when it was last updated.&lt;/p&gt;

&lt;p&gt;Between two ostensibly identical pods, the following vary without warning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CUDA version&lt;/strong&gt;: One pod runs CUDA 12.1, the next runs 12.6, the next runs 12.8&lt;br&gt;
&lt;strong&gt;PyTorch build&lt;/strong&gt;: A cu118 build behaves differently from cu121 and cu128, particularly around custom kernels and FlashAttention&lt;br&gt;
&lt;strong&gt;System libraries&lt;/strong&gt;: gcc version, glibc, NVIDIA driver revision&lt;br&gt;
&lt;strong&gt;Pre-installed ML packages&lt;/strong&gt;: One image ships transformers 4.41, another ships 4.48&lt;/p&gt;

&lt;p&gt;None of these differences crash your SSH session. The pod boots fine, nvidia-smi shows the GPU, your /workspace mounts cleanly. The divergence is invisible until your script hits the specific dependency that behaves differently on this image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How drift breaks training&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Environment drift rarely produces a clean early traceback. It fails in three ways:&lt;/p&gt;

&lt;p&gt;Silent CPU fallback&lt;/p&gt;

&lt;p&gt;If the PyTorch build on the image does not align with the underlying CUDA driver, torch.cuda.is_available() can return False without throwing an exception. Your script resolves device to CPU and keeps running.&lt;/p&gt;

&lt;p&gt;I hit this on a real Vast.ai run iteration time jumped from 0.4 seconds to 24 seconds. GPU utilisation: 0%. The script ran to completion at CPU speed while billing at full GPU rates.&lt;/p&gt;

&lt;p&gt;Adding an explicit guard prevents this:&lt;/p&gt;




&lt;p&gt;python&lt;br&gt;
import torch&lt;br&gt;
if not torch.cuda.is_available():&lt;br&gt;
    raise RuntimeError("CUDA unavailable refusing to start training")&lt;/p&gt;




&lt;p&gt;Dependency version mismatch&lt;/p&gt;

&lt;p&gt;Running ModernBERT requires transformers&amp;gt;=4.48.0. A pod with an older base image ships 4.41. The model may load via remote code but behave incorrectly, or fail partway through the first epoch with an obscure attribute error. The failure is not at import it is 40 minutes into your run.&lt;/p&gt;

&lt;p&gt;Accelerate configuration mismatch&lt;/p&gt;

&lt;p&gt;Your Accelerate config was created on a 2-GPU node with num_processes: 2. Your new pod has one GPU. The launcher may hang, produce garbage output, or corrupt checkpoints. No error at launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this is expensive to debug&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Environment drift failures share one trait: they are invisible at pod start. The GPU is visible, the script launches, everything looks normal. The failure surfaces at the first forward pass, the first checkpoint save, or not at all if the job completes but produces wrong output.&lt;/p&gt;

&lt;p&gt;By the time you notice, you have paid for the compute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to check before every new pod&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;-# Verify PyTorch can see the GPU&lt;/p&gt;

&lt;p&gt;python3 -c "import torch; print(torch.&lt;strong&gt;version&lt;/strong&gt;, torch.version.cuda, torch.cuda.is_available())"&lt;/p&gt;

&lt;p&gt;-# Check key package versions&lt;/p&gt;

&lt;p&gt;pip show transformers accelerate | grep Version&lt;/p&gt;




&lt;p&gt;Or run all of this plus HF_HOME path, persistent volume detection, and disk headroom in one command before billing starts:&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;The check takes under 30 seconds.&lt;/p&gt;

&lt;p&gt;The honest framing&lt;/p&gt;

&lt;p&gt;The CPU fallback failure is confirmed from my own Vast.ai runs. The CUDA version variance is confirmed from my A40 session PyTorch 2.8.0+cu128 on that specific pod, not universal. The dependency and Accelerate examples are well-understood engineering realities, not personal war stories.&lt;/p&gt;

&lt;p&gt;The point is not that every new pod will break your script. It is that a new pod is a new environment and treating it as identical to the last one is an assumption worth checking before the meter starts running.&lt;/p&gt;

&lt;p&gt;Your last pod working is evidence that your setup worked once. It is not proof that your next pod is ready.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>mlops</category>
      <category>runpod</category>
    </item>
    <item>
      <title>Why Axolotl Users On RunPod Lose Checkpoints Silently And How To Catch It Before Your Job Starts</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Thu, 15 Oct 2026 21:25:39 +0000</pubDate>
      <link>https://dev.to/franciscobooth/why-axolotl-users-on-runpod-lose-checkpoints-silently-and-how-to-catch-it-before-your-job-starts-3i5e</link>
      <guid>https://dev.to/franciscobooth/why-axolotl-users-on-runpod-lose-checkpoints-silently-and-how-to-catch-it-before-your-job-starts-3i5e</guid>
      <description>&lt;p&gt;Axolotl is one of the cleanest fine-tuning frameworks available. The problem is not Axolotl. The problem is what happens to your checkpoints when you run it on a rented GPU pod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I found running Axolotl on a real RunPod A40&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Last night I spun up a RunPod A40 pod at $0.59 per hour with a 10GB network volume mounted at /workspace. I installed ComputeFence and then installed Axolotl 0.20.0.&lt;/p&gt;

&lt;p&gt;Before launching any training job I ran:&lt;/p&gt;




&lt;p&gt;computefence doctor&lt;/p&gt;




&lt;p&gt;Here is the exact output:&lt;/p&gt;




&lt;p&gt;ComputeFence v0.2.11 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/p&gt;

&lt;p&gt;4 WARNINGS  ·  0 BLOCKERS  ·  4 PASSED&lt;/p&gt;

&lt;p&gt;Environment&lt;br&gt;
  ✓ Python 3.12.3&lt;br&gt;
  ✓ PyTorch 2.8.0+cu128 detected (CUDA available — NVIDIA A40)&lt;br&gt;
  ⚠ No Accelerate config found — skipping GPU count check&lt;br&gt;
    Fix: Run 'accelerate config' to create a configuration file&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ✓ HF_HOME is set to /workspace/.cache/huggingface/&lt;br&gt;
  ✓ Persistent volume(s) detected: /workspace&lt;br&gt;
  ⚠ Volume /workspace — 6.0 GB free of 9.3 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;br&gt;
  ⚠ Root disk (/) — 16.2 GB free of 20.0 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;/p&gt;

&lt;p&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
4 warning(s) found. Review before launching.&lt;/p&gt;




&lt;p&gt;The GPU passed. HF_HOME passed correctly pointing to the persistent volume. But the disk warning was real and would have caused a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the disk warning matters for Axolotl specifically&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Axolotl is not a small install. Its dependency tree pulled in over 200 packages torch, transformers, accelerate, flash-attention, deepspeed, gradio, and dozens more. By the time the install finished, my 10GB network volume had 6GB free and my root disk had 16.2GB free. Both below the 20GB safe threshold.&lt;/p&gt;

&lt;p&gt;Axolotl saves checkpoints during training. If you are fine-tuning a 7B model with save_steps: 100, checkpoints can be several gigabytes each. With 6GB free on the workspace volume, a checkpoint save mid-run would fail. The job would die without completing. The weights you had trained up to that point would be gone.&lt;/p&gt;

&lt;p&gt;No error before the job starts. No warning from Axolotl. Just a failed save at step 100 or 200 or wherever the disk fills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two options before launching:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1 - Attach a larger volume&lt;/strong&gt;&lt;br&gt;
If you are planning a long fine-tuning run, attach at least a 50GB network volume. Axolotl’s dependencies alone consume 3–4GB. Your base model weights consume more. Leave headroom for checkpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2 — Configure checkpoint saving to the persistent volume explicitly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your Axolotl config:&lt;/p&gt;




&lt;p&gt;output_dir: /workspace/outputs&lt;/p&gt;




&lt;p&gt;Not /root/outputs. Not a relative path. Explicitly /workspace/outputs so checkpoints land on the persistent volume, not the ephemeral root disk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run this before every Axolotl job&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;pip install computefence &amp;amp;&amp;amp; computefence doctor&lt;/p&gt;

&lt;p&gt;Or without installing:&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;It checks GPU visibility, HF_HOME path, persistent volume detection, and disk headroom before billing starts. The whole check takes under 30 seconds.&lt;/p&gt;

&lt;p&gt;The disk warning it caught on my A40 pod was real. If I had launched a training job immediately after installing Axolotl without checking, the job would have run until the first checkpoint save and died.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>runpod</category>
      <category>axolotl</category>
    </item>
    <item>
      <title>Why HF_HOME Points To Ephemeral Storage On RunPod By Default And How To Fix It</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Sun, 11 Oct 2026 14:23:40 +0000</pubDate>
      <link>https://dev.to/franciscobooth/why-hfhome-points-to-ephemeral-storage-on-runpod-by-default-and-how-to-fix-it-4d8m</link>
      <guid>https://dev.to/franciscobooth/why-hfhome-points-to-ephemeral-storage-on-runpod-by-default-and-how-to-fix-it-4d8m</guid>
      <description>&lt;p&gt;If you have ever run a HuggingFace model download on RunPod and come back to find your cache gone, this is why.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The default is wrong for rented GPU pods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HuggingFace sets HF_HOME to ~/.cache/huggingface when no environment variable overrides it. On a standard Linux machine that is fine your home directory persists. &lt;/p&gt;

&lt;p&gt;On RunPod, your home directory is on the container volume, which is ephemeral. When the pod stops, it is gone.&lt;/p&gt;

&lt;p&gt;RunPod has two storage layers: the container volume, which is ephemeral, and the network volume mounted at /workspace, which persists across pod restarts. HF_HOME defaults to the wrong one.&lt;/p&gt;

&lt;p&gt;This means every model download, every tokeniser, every dataset you pulled via datasets.load_dataset() gone on pod restart. You pay to download them again on the next run. &lt;/p&gt;

&lt;p&gt;On large models that is not a minor inconvenience. A 7B model download at pod startup adds minutes and real cost every single time.&lt;/p&gt;

&lt;p&gt;The fix is one line in your startup script:&lt;/p&gt;




&lt;p&gt;export HF_HOME=/workspace/.cache/huggingface&lt;/p&gt;




&lt;p&gt;/workspace is RunPod’s persistent volume mount. One line and your cache survives every restart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this is easy to miss&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no error message. HuggingFace downloads the files successfully to the ephemeral path. Your training run completes. The problem only surfaces when you restart the pod and the download happens again and even then it looks like a slow startup, not a misconfiguration.&lt;/p&gt;

&lt;p&gt;Silent failures are the hardest to debug because you are not looking for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automating the check&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want this caught automatically before every job rather than relying on remembering to set the variable, ComputeFence checks it as part of its pre-flight scan:&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;It flags HF_HOME pointing to ephemeral storage and prints the exact export command for your platform. It also checks GPU visibility, Accelerate config, checkpoint directory persistence, and disk headroom the other silent failures that cost compute budget without a log entry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The two-line pre-flight for every RunPod job&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;export HF_HOME=/workspace/.cache/huggingface&lt;br&gt;
uvx computefence doctor&lt;/p&gt;




&lt;p&gt;The first line fixes the cache. The second confirms everything else is configured correctly before the GPU bill starts.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>runpod</category>
      <category>mlops</category>
    </item>
    <item>
      <title>My GPU Training Job Ran for 20 Hours and Produced Nothing. There Was No Error Message.</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Tue, 06 Oct 2026 20:12:49 +0000</pubDate>
      <link>https://dev.to/franciscobooth/my-gpu-training-job-ran-for-20-hours-and-produced-nothing-there-was-no-error-message-20l1</link>
      <guid>https://dev.to/franciscobooth/my-gpu-training-job-ran-for-20-hours-and-produced-nothing-there-was-no-error-message-20l1</guid>
      <description>&lt;p&gt;I was fine-tuning the Exolio AI classifier that detects machine-generated texts. The classifier can be seen at huggingface.co/FranciscoBooth1/exolio-ai-detector.&lt;/p&gt;

&lt;p&gt;Between January and April 2026, I ran dozens of training jobs using Vast.ai. Cost of runs: approximately £1,000.&lt;/p&gt;

&lt;p&gt;All of the eventually identified failed runs had one thing in common: none of them gave me an obvious sign that they had failed.&lt;/p&gt;




&lt;p&gt;The run that ran all night and gave no output&lt;/p&gt;

&lt;p&gt;For Exolio v15, I was switching from DeBERTa-v3-large to ModernBERT. I rented a machine, uploaded the training script, installed dependencies, and initiated the run.&lt;/p&gt;

&lt;p&gt;Everything in the terminal looked exactly as expected:&lt;/p&gt;




&lt;p&gt;Uploading training script...&lt;br&gt;
Installing Python dependencies (this may take several minutes)...&lt;br&gt;
[Dependencies installed successfully]&lt;br&gt;
Starting training in tmux session 'ssh_tmux'...&lt;br&gt;
Training started successfully! Instance will auto-destroy when complete.&lt;/p&gt;




&lt;p&gt;The script returned to my local terminal and training started running in tmux on the remote machine. There was no way to monitor what happened inside that tmux session. Everything looked good. I went to sleep.&lt;/p&gt;

&lt;p&gt;The next day I tried to SSH back in:&lt;/p&gt;




&lt;p&gt;ssh: connect to host [instance IP] port 55157: Connection refused&lt;/p&gt;




&lt;p&gt;The instance was gone. The log files disappeared along with it. I checked my HuggingFace repository to see if there were any results:&lt;/p&gt;




&lt;p&gt;Last modified: 2026-04-12 01:20:33+00:00&lt;br&gt;
  .gitattributes&lt;br&gt;
  config.json&lt;br&gt;
  deberta_3class_latest.zip&lt;br&gt;
  model.safetensors&lt;br&gt;
  tokenizer.json&lt;br&gt;
  training_args.bin&lt;/p&gt;




&lt;p&gt;There was no modernbert_latest.zip. The last modification time was April 12 which was the previous DeBERTa run. No new files had been added.&lt;/p&gt;

&lt;p&gt;That was the only sign that something had gone wrong. Not an error message. Not a bad benchmark score. Absence of new files.&lt;/p&gt;

&lt;p&gt;I could not recover the logs the instance auto-destroyed and took everything with it so I cannot identify the root cause. Twenty hours had passed, the instance was gone, and no new model had appeared in my HuggingFace repository. &lt;/p&gt;

&lt;p&gt;I ran a training job, nothing obviously failed, and after twenty hours the infrastructure disappeared and there was no artifact left. I was not able to tell exactly why.&lt;/p&gt;




&lt;p&gt;Another failure: training on CPU for hours without knowing&lt;/p&gt;

&lt;p&gt;Earlier in the same period I rented what seemed to be a good machine and started fine-tuning DeBERTa. The loss function was printing. The iteration counter was counting. Everything was going as expected.&lt;/p&gt;

&lt;p&gt;Except the speed was wrong. I saw approximately 24 seconds per iteration. On working instances the same workload had been around 0.4 seconds per iteration.&lt;/p&gt;

&lt;p&gt;I ran nvidia-smi. GPU utilisation: 0%.&lt;/p&gt;

&lt;p&gt;My script resolved the device to CPU because torch.cuda.is_available() returned False no exception thrown, just CPU. The machine had CUDA installed but my PyTorch environment could not see the GPU. Training continued on CPU with no errors while I was paying full GPU rates.&lt;/p&gt;

&lt;p&gt;I stopped the run. Rented a different machine. Restarted.&lt;/p&gt;




&lt;p&gt;The pattern&lt;/p&gt;

&lt;p&gt;In both cases there was no error message that I could act on. In the first case there was no way to know anything had gone wrong until I tried to SSH back in. In the second case I noticed a strange iteration speed and stopped the job.&lt;/p&gt;

&lt;p&gt;In the second case the problem was visible before python train.py. torch.cuda.is_available() returning False is visible before the job starts. GPU utilisation at 0% is visible within seconds of launch.&lt;/p&gt;

&lt;p&gt;Additionally and not as an explanation of the overnight run, since I had no logs there are other silent failure modes that are also detectable before the training job starts. At least some of the conditions surrounding these failures were detectable before python train.py if I had known to check them:&lt;/p&gt;

&lt;p&gt;Whether PyTorch could see the GPU: torch.cuda.is_available() returns False before the job starts&lt;br&gt;
Whether the HuggingFace cache was configured to use a potentially ephemeral path: an environment variable check&lt;br&gt;
Whether the checkpoint output directory was under a known instance-local prefix: a path check&lt;/p&gt;

&lt;p&gt;None of these checks were complicated. I just did not perform them systematically on each new machine.&lt;/p&gt;




&lt;p&gt;What I built&lt;/p&gt;

&lt;p&gt;After enough of these I decided to build a pre-flight checker. One command before each training job:&lt;/p&gt;




&lt;p&gt;pip install computefence &amp;amp;&amp;amp; computefence doctor&lt;/p&gt;




&lt;p&gt;Or without installing the package:&lt;/p&gt;




&lt;p&gt;uvx computefence doctor&lt;/p&gt;




&lt;p&gt;Real output from uvx computefence doctor on my local Mac — on a real GPU pod the PyTorch and volume checks run against actual hardware:&lt;/p&gt;




&lt;p&gt;ComputeFence v0.2.6 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/p&gt;

&lt;p&gt;5 WARNINGS  ·  0 BLOCKERS  ·  1 PASSED&lt;/p&gt;

&lt;p&gt;Environment&lt;br&gt;
  ✓ Python 3.14.3&lt;br&gt;
  ⚠ PyTorch not found — skipping GPU checks&lt;br&gt;
    Fix: pip install torch torchvision torchaudio&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ⚠ HF_HOME is not set. HuggingFace may cache to instance-local storage&lt;br&gt;
    that is not persistent across pod termination.&lt;br&gt;
    Fix: Set HF_HOME to a persistent volume path before training&lt;br&gt;
  ⚠ No mounted persistent volumes detected at /workspace, /runpod-volume, or /vast&lt;br&gt;
    Fix: Mount a network volume at /workspace before launching your job&lt;br&gt;
  ⚠ Root disk (/) — 12.1 GB free of 460.4 GB (below 20 GB)&lt;br&gt;
    Fix: Free up disk space or move checkpoints to a larger volume&lt;/p&gt;

&lt;p&gt;Dataset&lt;br&gt;
  ⚠ No dataset path provided — skipping dataset checks&lt;/p&gt;

&lt;p&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
5 warning(s) found. Review before launching.&lt;/p&gt;




&lt;p&gt;Checks:&lt;/p&gt;

&lt;p&gt;1) GPU and CUDA visibility - fails if torch.cuda.is_available() returns False; reports relevant CUDA and PyTorch version information and warns on detected version skew&lt;/p&gt;

&lt;p&gt;2) HuggingFace cache path — warns if HF_HOME is not set or points to a path known to be instance-local on supported providers.&lt;/p&gt;

&lt;p&gt;3) Accelerate configuration — warns if there is an inconsistency between the configured number of processes and the GPUs visible in the environment.&lt;/p&gt;

&lt;p&gt;4) Disk headroom — warns when less than 20 GB is available; blocks if less than 5 GB is available.&lt;/p&gt;

&lt;p&gt;5) Checkpoint output directory — warns if the path is under known instance-local prefixes that may not survive pod termination.&lt;/p&gt;

&lt;p&gt;6) Dataset — optionally checks for duplicates and conflicting labels with --dataset.&lt;/p&gt;

&lt;p&gt;Checks that it does not do: training script correctness, model architecture, learning rate safety, runtime behaviour during training, or GPU utilisation during training. ComputeFence is a pre-flight check. It does not monitor the running job.&lt;/p&gt;

&lt;p&gt;A passing check does not guarantee that the training job will succeed.&lt;/p&gt;

&lt;p&gt;The pre-flight check took under 30 seconds on my test pod.&lt;/p&gt;




&lt;p&gt;The ask&lt;/p&gt;

&lt;p&gt;ComputeFence is free, open source, and MIT licensed.&lt;/p&gt;

&lt;p&gt;If you run training jobs on Vast.ai, RunPod, or any other rented GPU, try uvx computefence doctor before your next run. If it finds something interesting, paste the output in the comments below.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;br&gt;
Install: pip install computefence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>mlops</category>
      <category>vastai</category>
    </item>
    <item>
      <title>24 seconds per iteration instead of 0.4. I paid for six hours of GPU compute and trained on CPU the entire time.</title>
      <dc:creator>Francisco Booth</dc:creator>
      <pubDate>Sun, 06 Sep 2026 10:22:30 +0000</pubDate>
      <link>https://dev.to/franciscobooth/24-seconds-per-iteration-instead-of-04-i-paid-for-six-hours-of-gpu-compute-and-trained-on-cpu-the-3p41</link>
      <guid>https://dev.to/franciscobooth/24-seconds-per-iteration-instead-of-04-i-paid-for-six-hours-of-gpu-compute-and-trained-on-cpu-the-3p41</guid>
      <description>&lt;p&gt;Failure 1 — CUDA silently fell back to CPU&lt;/p&gt;

&lt;p&gt;My training job launched on Vast.ai and ran to completion. Iteration time was 24 seconds instead of 0.4 seconds. CUDA had fallen back to CPU silently. PyTorch logged nothing. I had been billed for six hours of GPU compute while training on an unaccelerated CPU thread the entire time.&lt;/p&gt;

&lt;p&gt;Failure 2 — HF_HOME on ephemeral disk&lt;/p&gt;

&lt;p&gt;Every fresh pod re-downloaded base model weights to /root/.cache — the ephemeral container disk wiped on pod shutdown. Same download, same cost, every run. The fix is one line. I did not know it for weeks.&lt;/p&gt;

&lt;p&gt;export HF_HOME=/workspace/.cache/huggingface&lt;/p&gt;

&lt;p&gt;Failure 3 — Accelerate config mismatch&lt;/p&gt;

&lt;p&gt;My accelerate config had num_processes: 2. The pod had one GPU. Training launched, appeared to run, and produced garbage output. No error thrown. The configuration simply did not match the hardware.&lt;/p&gt;

&lt;p&gt;Failure 4 — Dirty dataset&lt;/p&gt;

&lt;p&gt;28,432 duplicate rows. 312 conflicting labels. Loss collapsed to 0.693 on step one — the exact cross-entropy value for random guessing on a binary classification problem. I spent three days debugging model architecture and learning rates before I scanned the dataset.&lt;/p&gt;

&lt;p&gt;The pattern&lt;/p&gt;

&lt;p&gt;None of these printed an exception. All of them were visible before python train.py if I had known what to check.&lt;/p&gt;

&lt;p&gt;I spoke to 13 ML engineers on RunPod, Vast.ai, and AWS. Nine had lost checkpoints to ephemeral disk. Eight had shipped silent garbage with no log error.&lt;/p&gt;

&lt;p&gt;An ML engineer at a major German industrial company told me his team maintains a five or six part manual bash script that they run before every GPU job because no standardised tool exists.&lt;/p&gt;

&lt;p&gt;When enterprise teams are hand-rolling bash scripts, the problem is real.&lt;/p&gt;

&lt;p&gt;So I built ComputeFence.&lt;/p&gt;

&lt;h1&gt;
  
  
  Standard install:
&lt;/h1&gt;

&lt;p&gt;pip install computefence&lt;br&gt;
computefence doctor&lt;/p&gt;

&lt;h1&gt;
  
  
  Zero install on a fresh pod:
&lt;/h1&gt;

&lt;p&gt;uvx computefence doctor&lt;/p&gt;

&lt;p&gt;30 seconds. Every warning prints the exact fix command.&lt;/p&gt;

&lt;p&gt;ComputeFence v0.2.5 — Pre-flight diagnostic&lt;br&gt;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
2 WARNINGS  ·  0 BLOCKERS  ·  3 PASSED&lt;/p&gt;

&lt;p&gt;Storage&lt;br&gt;
  ⚠ HF_HOME is not set — model weights will cache to ephemeral disk&lt;br&gt;
    Fix: export HF_HOME=/workspace/.cache/huggingface&lt;br&gt;
  ⚠ Root disk (/) — 14.3 GB free (below 20 GB)&lt;br&gt;
    Fix: Free up disk or move checkpoints: df -h to check usage&lt;/p&gt;

&lt;p&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;br&gt;
2 warning(s) found. Review before launching.&lt;/p&gt;

&lt;p&gt;It checks GPU and CUDA visibility, HuggingFace cache path persistence, Accelerate GPU count versus what is actually on the instance, disk headroom for checkpoints, and checkpoint output directory persistence via --output-dir.&lt;/p&gt;

&lt;p&gt;It does not check training script correctness, learning rate safety, or anything that only fails during the run. HuggingFace cache and your checkpoint output directory are separate paths — fixing one does not fix the other. ComputeFence catches configuration mistakes before the GPU starts billing.&lt;/p&gt;

&lt;p&gt;Add it to your pod startup script. Exit code is 0 on warnings and 1 only on hard blockers so training will still launch on warnings:&lt;/p&gt;

&lt;p&gt;pip install computefence &amp;amp;&amp;amp; computefence doctor &amp;amp;&amp;amp; python train.py&lt;/p&gt;

&lt;p&gt;Does it catch anything real?&lt;/p&gt;

&lt;p&gt;Three operators have run it before paid training jobs on RunPod.&lt;/p&gt;

&lt;p&gt;One caught HF_HOME writing to ephemeral disk and an Accelerate config mismatch on a RunPod A100. He fixed both before launch.&lt;/p&gt;

&lt;p&gt;One confirmed the storage warning matched real pod behaviour and said he would not have caught it without the tool.&lt;/p&gt;

&lt;p&gt;Aaron, an ML engineer who ran ComputeFence on a RunPod A40, said the Accelerate warning would have made him stop and investigate before launching.&lt;/p&gt;

&lt;p&gt;Still very early.&lt;/p&gt;

&lt;p&gt;If you run it before your next paid job on RunPod, Vast.ai, Lambda Labs, or any bare metal instance — paste your computefence doctor output in the comments or open an issue on GitHub. I want to know which checks fire on real setups and which are noise.&lt;/p&gt;

&lt;p&gt;Free. MIT licensed. Works on any bare metal GPU provider.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Francisco-Booth/ComputeFence&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>opensource</category>
      <category>gpu</category>
    </item>
  </channel>
</rss>
