| name | pytorch-testing-logging |
| description | Run PyTorch unit tests, save results to NumPy files, and log environment information for reproducibility. Use this skill when executing test suites for neural network functions, validating loss computations, saving tensor outputs for verification, and creating reproducibility logs with Python/package versions. |
PyTorch Testing and Results Logging
Overview
This skill covers running unit tests for PyTorch functions, verifying outputs, saving results in standardized formats (NumPy .npz), and logging environment information for complete reproducibility of machine learning experiments.
Unit Test Execution
Running PyTorch Unit Tests
Basic Test Execution
python -m pytest unit_test/unit_test_1.py -v
python -m unittest unit_test.unit_test_1 -v
python unit_test/unit_test_1.py
Test Output Flags
-v or --verbose
-s or --capture=no
-x or --exitfirst
-l or --showlocals
Running Specific Tests
python -m pytest unit_test/unit_test_1.py::TestModelOutputs::test_random_pairs -v
python -m pytest unit_test/ -k "test_loss" -v
Handling Test Issues
ImportError - Module Not Found
export PYTHONPATH=/path/to/project:$PYTHONPATH
python unit_test/unit_test_1.py
cd /root/SimPO
python -m pytest unit_test/unit_test_1.py
Device/CUDA Issues in Tests
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
tensor = tensor.to(device)
File Path Resolution
Tests often use relative paths. Run from:
- Project root directory
- Or ensure test adjusts paths with
Path(__file__).resolve().parent
Saving Results to NumPy Format
NPZ File Format (Recommended for Multi-Array Storage)
Writing Results
import numpy as np
import torch
losses = torch.tensor([0.5, 0.3, 0.7])
np.savez(
"/root/loss.npz",
losses=losses.detach().cpu().numpy()
)
np.savez(
"/root/results.npz",
losses=losses.detach().cpu().numpy(),
rewards_chosen=chosen_rewards.detach().cpu().numpy(),
rewards_rejected=rejected_rewards.detach().cpu().numpy()
)
Reading Saved Results
import numpy as np
data = np.load("/root/loss.npz")
losses = data['losses']
data = np.load("/root/results.npz")
losses = data['losses']
chosen_rewards = data['rewards_chosen']
print(data.keys())
Converting PyTorch Tensors to NumPy
Device-Agnostic Conversion
numpy_array = tensor.detach().cpu().numpy()
gpu_tensor = torch.randn(10, device="cuda")
numpy_array = gpu_tensor.detach().cpu().numpy()
tensor_cpu = tensor.cpu()
numpy_array = tensor_cpu.numpy()
Preserving Precision
numpy_array = tensor.numpy()
numpy_array = tensor.detach().cpu().numpy().astype(np.float32)
numpy_array = tensor.detach().cpu().numpy().astype(np.float64)
Environment Logging for Reproducibility
Comprehensive Environment Information
Python Version and Build
python -VV
Package Freeze
python -m pip freeze
python -m pip freeze > environment_info.txt
{
echo "=== Environment Log - $(date) ==="
echo
echo "=== Python Version ==="
python -VV
echo
echo "=== Installed Packages ==="
python -m pip freeze
echo
echo "=== Key Package Versions ==="
python -c "import torch; print(f'torch: {torch.__version__}')"
python -c "import transformers; print(f'transformers: {transformers.__version__}')"
} > /root/python_info.txt
Creating Reproducibility Log
{
echo "=== Environment Information ==="
echo "Timestamp: $(date)"
echo "Hostname: $(hostname)"
echo "Platform: $(python -c 'import platform; print(platform.platform())')"
echo
echo "=== Python Version ==="
python -VV
echo
echo "=== All Installed Packages ==="
python -m pip freeze
echo
echo "=== CUDA/Device Info ==="
python -c "import torch; print(f'CUDA Available: {torch.cuda.is_available()}'); print(f'Device: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"CPU\"}')"
} > /root/python_info.txt
Logging During Test Execution
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/root/test.log'),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
logger.info(f"Test started with device: {device}")
logger.info(f"Input shapes: chosen={chosen_logps.shape}, rejected={rejected_logps.shape}")
logger.info(f"Loss computation completed")
Complete Test-to-Save Workflow
Pattern for Loss Function Testing
import torch
import numpy as np
import unittest
from pathlib import Path
class TestLossFunction(unittest.TestCase):
def setUp(self):
self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
self.chosen_logps = torch.load("unit_test/tensors/policy_chosen_logps.pt").to(self.device)
self.rejected_logps = torch.load("unit_test/tensors/policy_rejected_logps.pt").to(self.device)
def test_loss_computation(self):
loss_fn = YourLossFunction()
losses, chosen_rewards, rejected_rewards = loss_fn(
self.chosen_logps,
self.rejected_logps
)
self.assertEqual(losses.shape, (len(self.chosen_logps),))
self.assertTrue(torch.all(losses >= 0))
np.savez(
"/root/loss.npz",
losses=losses.detach().cpu().numpy(),
chosen_rewards=chosen_rewards.detach().cpu().numpy(),
rejected_rewards=rejected_rewards.detach().cpu().numpy()
)
print()
__name__ == :
unittest.main()
Verification Checklist
After running tests and saving results:
-
Check Output File
ls -lh /root/loss.npz
-
Verify File Contents
import numpy as np
data = np.load("/root/loss.npz")
print(f"Keys: {list(data.keys())}")
print(f"Losses shape: {data['losses'].shape}")
print(f"Loss values sample: {data['losses'][:5]}")
-
Validate Loss Properties
losses = data['losses']
print(f"Min loss: {losses.min()}, Max loss: {losses.max()}")
print(f"Mean loss: {losses.mean()}, Std: {losses.std()}")
print(f"No NaN values: {not np.any(np.isnan(losses))}")
print(f"No Inf values: {not np.any(np.isinf(losses))}")
-
Check Environment Log
head -20 /root/python_info.txt
Common Issues and Solutions
Issue: ImportError in Test
Solution: Ensure Python path includes project root
cd /root/SimPO
export PYTHONPATH=/root/SimPO:$PYTHONPATH
python -m pytest unit_test/unit_test_1.py -v
Issue: Tensor on Wrong Device
Solution: Check device placement
if self.device.type == 'cuda':
tensor = tensor.cuda()
else:
tensor = tensor.cpu()
Issue: NPZ File Not Created
Solution: Verify directory exists and is writable
touch /root/test.npz
ls -l /root/
Issue: NumPy Conversion from GPU Tensor
Solution: Always detach and move to CPU
numpy_array = tensor.numpy()
numpy_array = tensor.detach().cpu().numpy()