Research workflows
Run and verify a PyTorch GPU notebook
Check compute and CUDA software separately, calculate on a GPU, and save device and result evidence.
Verify that a Python notebook can actually use a CUDA GPU, perform a tiny calculation on it, and save enough information for a collaborator to check the result. The example distinguishes an installed GPU-capable framework from an accessible GPU device.
Check compute and software separately
You need an editable CoCalc project running on a host with an NVIDIA GPU exposed to that project, a compatible host driver, and a Python Jupyter kernel with CUDA-enabled PyTorch. An image name or a successful package import does not establish GPU access. Availability depends on the deployment, host, region, capacity, and your access to that host.
- Check the intended host and project placement using Use project hosts. Use Move projects between hosts when appropriate; do not assume changing a software image allocates different hardware.
- In the full project interface, open Settings -> Environment. Under Image, choose Details and inspect the selected runtime image. Follow Project images if it must change. Save ongoing work before applying a change that restarts the project.
- Choose an available image containing CUDA-enabled PyTorch, or have the
environment prepared using a compatible recipe. The source repository's
ml-pytorch-gpuexample installs a Python Jupyter environment andcocalc/pytorch-gpu. A recipe existing in source does not mean its resulting image is published or accessible on your deployment. - In a new
gpu-demofolder, creategpu-check.ipynb. In its full notebook editor use Kernel -> Change Kernel... to select the Python kernel belonging to that environment, then save the notebook.
For a first notebook, use Start and hand off a research task. The commands below run in notebook code cells, not in the terminal.
If your GPU is on a separately managed machine, consider
Remote Jupyter kernels instead. With a remote
kernel, these cells execute on that machine and gpu-result.json is written
to its filesystem. Transfer the checked result back into the CoCalc project
before following the file-browser and handoff steps below.
Run the preflight in the notebook kernel
import sys
import torch
print("python:", sys.executable)
print("torch:", torch.__version__)
print("cuda build:", torch.version.cuda)
print("gpu available:", torch.cuda.is_available())
print("visible device count:", torch.cuda.device_count())
if not torch.version.cuda:
raise RuntimeError("This notebook kernel has a PyTorch build without CUDA")
if not torch.cuda.is_available():
raise RuntimeError("No CUDA GPU is accessible from this notebook kernel")
print("device:", torch.cuda.get_device_name(0))
Expected: a Python executable path, installed PyTorch and CUDA build versions,
gpu available: True, a positive device count, and a GPU device name.
Exact paths, versions, and names vary. Stop here if either preflight check
fails; a CPU fallback would not verify the GPU workflow.
The source recipe's verifier makes the same distinction: it checks that the
wheel is CUDA-enabled, and only requires a visible GPU when its
require_gpu setting is true. The sample image recipe uses false so that
an image can be built without a GPU attached. Consequently, an image build
passing verification is not a successful notebook GPU test.
Compute on the GPU and save the evidence
Run this as the next cell in the same notebook. It writes a JSON result to the notebook kernel's working directory and refuses to replace an existing result. If rerunning, choose a new result filename deliberately.
import json
import platform
from pathlib import Path
output = Path("gpu-result.json")
if output.exists():
raise FileExistsError(f"Choose a new result filename: {output.resolve()}")
values = torch.tensor([2.0, 4.0, 6.0, 8.0], device="cuda:0")
mean = values.mean()
torch.cuda.synchronize()
assert values.is_cuda
assert mean.is_cuda
assert mean.item() == 5.0
record = {
"python_version": platform.python_version(),
"python_executable": sys.executable,
"torch_version": str(torch.__version__),
"cuda_build_version": torch.version.cuda,
"device": str(values.device),
"device_name": torch.cuda.get_device_name(values.device),
"input_values": [2.0, 4.0, 6.0, 8.0],
"count": values.numel(),
"mean": mean.item(),
}
with output.open("x") as stream:
json.dump(record, stream, indent=2)
stream.write("\n")
print(f"count={record['count']}")
print(f"mean={record['mean']:.1f}")
print(f"device={record['device']}")
print("saved:", output.resolve())
Expected calculation output:
count=4
mean=5.0
device=cuda:0
The final line gives the absolute location of gpu-result.json. Open that
file in Files and inspect its device, framework versions, inputs, and
result. Save the notebook, reload it, and confirm that both the code and output
remain. This tiny example demonstrates device execution; it is not a GPU
performance benchmark or a guarantee that a larger model fits in memory.
Diagnose the failing layer
| Observation | Next check |
|---|---|
ModuleNotFoundError: No module named 'torch' |
Check sys.executable in this notebook and select the kernel for the prepared environment. A terminal's Python can be different. |
torch.version.cuda is None |
The selected kernel has a non-CUDA build. Correct the environment before investigating GPU allocation. |
| CUDA build version exists, but availability is false. | Check project placement, GPU exposure, and driver compatibility with the host operator. In a project terminal, nvidia-smi can provide driver/device diagnostics when installed; its absence alone does not identify the cause. |
| Allocation or out-of-memory error | Inspect device usage, reduce the workload, and release unused tensors or restart this kernel. The tiny check should precede a full training run. |
| The result is correct but the saved file is missing from the expected folder. | Use the absolute path printed by the cell. Check the notebook's working directory rather than assuming it matches the directory shown in Files. |
When asking for help, include the preflight output, intended image, and exact error. Review output before sharing it externally; avoid sharing unrelated project files or credentials.
Hand off and release compute
Keep gpu-check.ipynb, gpu-result.json, the selected image identifier,
and a brief README together. State that the result was calculated on CUDA,
which GPU and framework were used, and that the next person needs equivalent
GPU access to repeat that device check. Use
Research handoff for collaborator access.
Save the notebook and result before shutting down its kernel. For an otherwise unused project, use the normal Stop… control under Settings -> Runtime after coordinating with collaborators. Stopping a project kills its processes; it is not the same as stopping an account-owned host. Manage any dedicated host separately using Project host lifecycle actions. Do not stop a shared host to clean up this example.