Environment Modules and Containers

Environment modules and containers are two ways to control software environments on research machines and HPC clusters. Modules expose shared system software; containers package a larger user-space environment.

The environment should be treated as part of the run contract:

The key boundary is host versus user space:

Containers package much of user space, but they still depend on host drivers, filesystem mounts, and scheduler integration.

Modules

Modules are useful when the site provides CUDA, compilers, MPI, and libraries centrally. They are lightweight but depend on cluster configuration.

Checks:

  • Record loaded module names and versions.
  • Avoid assuming the same default module set across machines.
  • Confirm that Python packages and binary libraries resolve to the intended stack.

Module Contract

FieldWhy It Matters
module names and versionsidentifies compiler, CUDA, MPI, and shared libraries
load orderlater modules can override paths
shell contextlogin shell and batch shell may load different defaults
environment variablesPATH, library paths, and runtime flags change behavior
Python environmentpackage resolver and binary wheels may not match module ABI

For public notes, record the class of stack rather than the private module tree. A useful public phrase is CUDA-compatible module stack with recorded compiler/runtime versions, not a site-specific module path.

Containers

Containers improve portability by packaging user-space dependencies. They still depend on host drivers, runtime support, storage mounts, and scheduler integration.

Checks:

  • Record container image name, digest, and build recipe.
  • Keep secrets and private data out of the image.
  • Verify GPU access, mounts, permissions, and working directory behavior.

Container Contract

FieldWhy It Matters
image tag and digesttag alone can move; digest pins content
base imagecontrols OS user-space and CUDA runtime family
build recipeexplains how the image was produced
entrypoint and commandaffects shell behavior and working directory
mounted pathscontrols data, logs, checkpoints, and permissions
GPU runtimehost driver must support the container runtime
UID/GID behavioraffects write permission and shared artifacts

Container reproducibility is strongest when image digest, code commit, config, and data version are recorded together.

Driver and Runtime Boundary

GPU containers do not carry the kernel driver. A typical stack is:

If a run fails after moving between machines, check this chain before changing model code.

SymptomPossible Boundary
GPU not visiblescheduler allocation, container runtime, device binding
CUDA initialization failsdriver/runtime compatibility
import works but kernels failframework build and compiled extension mismatch
run works interactively but not in jobbatch shell, module load, mount, or environment variable
checkpoint cannot loadpackage, model code, or serialization version drift

Choosing Modules or Containers

NeedPreferCaveat
site-provided MPI or scheduler integrationmodulesless portable across clusters
reproducible Python package stackcontainer or lockfilestill depends on host driver and mounts
quick interactive debuggingmodules or lightweight envdefaults may differ from batch jobs
long public reproductioncontainer digest plus run recordavoid private registry or data paths
custom compiled extensionscontainer or explicit build scriptABI must match CUDA/compiler stack

Run Record Fields

A public-safe run record should include enough environment detail to explain compatibility without exposing infrastructure.

FieldPublic-Safe Form
OS classLinux x86_64 or similar class
accelerator stackCUDA/runtime family, framework build
package environmentlockfile, frozen package list, or image digest
module/container stategeneric module list or image digest
hardware classGPU class or CPU class, not private hostname
launch modeinteractive, batch job, containerized, distributed
known drifttraining/evaluation/inference environment differences

Public Notes

  • Describe generic environment strategy.
  • Do not publish private registry names, internal mount paths, credentials, or host-specific module trees.
  • Do not paste full environment dumps if they include usernames, private paths, tokens, internal registries, hostnames, or mount topology.
  • Prefer summarized compatibility fields and keep full private logs outside the public blog.

Checks

  • Is this a systems concept, or an operational failure that belongs in Server operations?
  • Can another reader understand the runtime boundary without private cluster details?
  • Are training, evaluation, and inference using the same environment or intentionally different ones?
  • Is the host driver/runtime boundary recorded for GPU work?
  • Are module defaults and batch-job environment differences accounted for?
  • Is the container pinned by digest rather than only by tag when reproducibility matters?