mirror of
https://github.com/hanzoai/gym-v1.git
synced 2026-11-02 15:10:54 +00:00
81 lines
3.3 KiB
Python
81 lines
3.3 KiB
Python
import os
|
|
import torch
|
|
import numpy as np
|
|
|
|
class CorrelationMixin:
|
|
def _correlation_calculation(self):
|
|
if self.num_nodes < 2:
|
|
raise Exception("Correlation calculation cannot be used with < 2 nodes")
|
|
|
|
# Ensure correlation is only calculated if interval is set
|
|
if not self.config.correlation_interval:
|
|
return None
|
|
|
|
# Create a temporary directory for this timestep's checkpoints
|
|
tmp_dir = os.path.join(self.config.save_dir, f"tmp_corr_{self.local_step}")
|
|
# Only rank 0 creates the directory to avoid race conditions
|
|
if self.rank == 0:
|
|
os.makedirs(tmp_dir, exist_ok=True)
|
|
torch.distributed.barrier() # Wait for rank 0 to create dir
|
|
|
|
# Save model state dict for each rank
|
|
checkpoint_path = os.path.join(tmp_dir, f"{self.rank}.pt")
|
|
torch.save(self.model.state_dict(), checkpoint_path)
|
|
|
|
# Wait for all processes to save their checkpoints
|
|
torch.distributed.barrier()
|
|
|
|
corr_value = None
|
|
if self.rank == 0:
|
|
# Load all models as vectors
|
|
model_vectors = []
|
|
for r in range(self.config.num_nodes):
|
|
model_path = os.path.join(tmp_dir, f"{r}.pt")
|
|
# Ensure the file exists before trying to load
|
|
if os.path.exists(model_path):
|
|
checkpoint = torch.load(model_path, map_location="cpu")
|
|
vector_list = []
|
|
for key in sorted(checkpoint.keys()):
|
|
value = checkpoint[key]
|
|
if isinstance(value, torch.Tensor):
|
|
vector_list.append(value.cpu().numpy().ravel())
|
|
if vector_list: # Check if we actually got any tensors
|
|
model_vectors.append(np.concatenate(vector_list))
|
|
else:
|
|
print(
|
|
f"Warning: Checkpoint file {model_path} not found for rank {r}."
|
|
)
|
|
|
|
if len(model_vectors) >= 2: # Need at least two models to compare
|
|
# Calculate correlations between all pairs
|
|
correlations = []
|
|
for i in range(len(model_vectors)):
|
|
for j in range(i + 1, len(model_vectors)):
|
|
corr = np.corrcoef(model_vectors[i], model_vectors[j])[0, 1]
|
|
correlations.append(corr)
|
|
|
|
if correlations: # Ensure correlations list is not empty
|
|
corr_value = np.mean(correlations)
|
|
|
|
# Log average correlation to wandb using the logger
|
|
if self.logger:
|
|
self.logger.log(data={"avg_model_correlation": corr_value})
|
|
else:
|
|
print(
|
|
"Warning: Could not calculate correlation, not enough valid model pairs."
|
|
)
|
|
else:
|
|
print(
|
|
f"Warning: Not enough models loaded ({len(model_vectors)}) to calculate correlation."
|
|
)
|
|
|
|
# Clean up temporary directory
|
|
import shutil
|
|
|
|
shutil.rmtree(tmp_dir)
|
|
|
|
# Wait for rank 0 to finish cleanup
|
|
torch.distributed.barrier()
|
|
|
|
return corr_value # Only rank 0 returns a value, others return None
|