Following this instruction :
1. Strictly adhere to PEP-8 standards, ensuring code is clean, well-structured, and follows Python's style guide for readability.
2. Use appropriate modules like `typing` for type hints, ensuring code clarity, maintainability, and leveraging Python's standard libraries effectively.
3. Focus on time, space, robustness, scalability; write optimized, efficient code that can handle large datasets and scale seamlessly.
4. Implement comprehensive error handling, catching exceptions gracefully, providing meaningful error messages, and ensuring code robustness under unexpected conditions.
5. Ensure the developer agent writes advanced, maintainable Python code, balancing performance and readability while adhering to best practices.

TASK : in the below code, axis is hard coding, legend , some beautification is missing, professional look is missing 

logic is correct



import os
import torch
import plotly.express as px
from plotly.graph_objs import Figure
from torch.nn import Module
from typing import Tuple, Any, Optional

def create_visualization_directory(directory: str) -> None:
    """
    Creates the visualization directory if it does not exist.

    Args:
        directory (str): Path to the directory.
    """
    try:
        os.makedirs(directory, exist_ok=True)
    except OSError as e:
        raise RuntimeError(f"Failed to create directory {directory}: {e}")

def save_plot(fig: Figure, filepath: str) -> None:
    """
    Saves the Plotly figure to an HTML file.

    Args:
        fig (Figure): Plotly figure object.
        filepath (str): Path to save the HTML file.
    """
    try:
        fig.write_html(filepath)
    except Exception as e:
        raise RuntimeError(f"Failed to save plot to {filepath}: {e}")

def plot_1d(param_name: str, param_tensor: torch.Tensor, output_dir: str) -> None:
    """
    Creates and saves a box plot for 1D tensor.

    Args:
        param_name (str): Name of the parameter.
        param_tensor (torch.Tensor): 1D tensor.
        output_dir (str): Directory to save the plot.
    """
    try:
        data = {
            'Values': param_tensor.detach().cpu().numpy()  # Modified line
        }
        fig = px.box(data, y='Values',
                     title=f'Box Plot for {param_name} | Shape: {param_tensor.shape}',
                     labels={'Values': 'Parameter Values'})
        filepath = os.path.join(output_dir, f"{param_name}_box_plot.html")
        save_plot(fig, filepath)
    except Exception as e:
        print(f"Error plotting 1D parameter '{param_name}': {e}")

def plot_2d(param_name: str, param_tensor: torch.Tensor, output_dir: str) -> None:
    """
    Creates and saves a scatter plot for 2D tensor.

    Args:
        param_name (str): Name of the parameter.
        param_tensor (torch.Tensor): 2D tensor.
        output_dir (str): Directory to save the plot.
    """
    try:
        if param_tensor.shape[0] < 2:
            raise ValueError("2D tensor must have at least two elements in the first dimension.")

        numpy_tensor = param_tensor.detach().cpu().numpy()  # Detached once
        data = {
            'X': numpy_tensor[:, 0],
            'Y': numpy_tensor[:, 1]
        }
        fig = px.scatter(data, x='X', y='Y',
                         title=f'Scatter Plot for {param_name} | Shape: {param_tensor.shape}',
                         labels={'X': 'Dimension 1', 'Y': 'Dimension 2'})
        filepath = os.path.join(output_dir, f"{param_name}_scatter_plot.html")
        save_plot(fig, filepath)
    except Exception as e:
        print(f"Error plotting 2D parameter '{param_name}': {e}")

def plot_3d(param_name: str, param_tensor: torch.Tensor, output_dir: str) -> None:
    """
    Creates and saves a 3D scatter plot for 3D tensor.

    Args:
        param_name (str): Name of the parameter.
        param_tensor (torch.Tensor): 3D tensor.
        output_dir (str): Directory to save the plot.
    """
    try:
        if param_tensor.ndim != 3:
            raise ValueError("Tensor is not 3D.")

        reshaped = param_tensor.view(-1, 3).detach().cpu().numpy()  # Detached
        data = {
            'X': reshaped[:, 0],
            'Y': reshaped[:, 1],
            'Z': reshaped[:, 2]
        }
        fig = px.scatter_3d(data, x='X', y='Y', z='Z',
                            title=f'3D Scatter Plot for {param_name} | Shape: {param_tensor.shape}',
                            labels={'X': 'Dimension 1', 'Y': 'Dimension 2', 'Z': 'Dimension 3'})
        filepath = os.path.join(output_dir, f"{param_name}_3d_scatter_plot.html")
        save_plot(fig, filepath)
    except Exception as e:
        print(f"Error plotting 3D parameter '{param_name}': {e}")

def plot_4d(param_name: str, param_tensor: torch.Tensor, output_dir: str) -> None:
    """
    Creates and saves a 3D scatter plot with color representing the 4th dimension for 4D tensor.

    Args:
        param_name (str): Name of the parameter.
        param_tensor (torch.Tensor): 4D tensor.
        output_dir (str): Directory to save the plot.
    """
    try:
        if param_tensor.ndim != 4:
            raise ValueError("Tensor is not 4D.")

        reshaped = param_tensor.view(-1, 4).detach().cpu().numpy()  # Detached
        data = {
            'X': reshaped[:, 0],
            'Y': reshaped[:, 1],
            'Z': reshaped[:, 2],
            'Color': reshaped[:, 3]
        }
        fig = px.scatter_3d(data, x='X', y='Y', z='Z',
                            color='Color',
                            title=f'4D Scatter Plot for {param_name} | Shape: {param_tensor.shape}',
                            labels={'X': 'Dimension 1', 'Y': 'Dimension 2', 'Z': 'Dimension 3', 'Color': 'Dimension 4'})
        filepath = os.path.join(output_dir, f"{param_name}_4d_scatter_plot.html")
        save_plot(fig, filepath)
    except Exception as e:
        print(f"Error plotting 4D parameter '{param_name}': {e}")

def plot_5d(param_name: str, param_tensor: torch.Tensor, output_dir: str) -> None:
    """
    Creates and saves a 3D scatter plot with color and size representing the 4th and 5th dimensions for 5D tensor.

    Args:
        param_name (str): Name of the parameter.
        param_tensor (torch.Tensor): 5D tensor.
        output_dir (str): Directory to save the plot.
    """
    try:
        if param_tensor.ndim != 5:
            raise ValueError("Tensor is not 5D.")

        reshaped = param_tensor.view(-1, 5).detach().cpu().numpy()  # Detached
        data = {
            'X': reshaped[:, 0],
            'Y': reshaped[:, 1],
            'Z': reshaped[:, 2],
            'Color': reshaped[:, 3],
            'Size': reshaped[:, 4]
        }
        fig = px.scatter_3d(data, x='X', y='Y', z='Z',
                            color='Color', size='Size',
                            title=f'5D Scatter Plot for {param_name} | Shape: {param_tensor.shape}',
                            labels={
                                'X': 'Dimension 1',
                                'Y': 'Dimension 2',
                                'Z': 'Dimension 3',
                                'Color': 'Dimension 4',
                                'Size': 'Dimension 5'
                            })
        filepath = os.path.join(output_dir, f"{param_name}_5d_scatter_plot.html")
        save_plot(fig, filepath)
    except Exception as e:
        print(f"Error plotting 5D parameter '{param_name}': {e}")

def visualize_model_parameters(model: Module, output_dir: str = "model_parameter_plots") -> None:
    """
    Visualizes parameters of a PyTorch model based on their dimensionality.

    Args:
        model (Module): The PyTorch model.
        output_dir (str, optional): Directory to save the plots. Defaults to "model_parameter_plots".
    """
    create_visualization_directory(output_dir)

    for name, param in model.named_parameters():
        if not param.requires_grad:
            continue  # Skip non-trainable parameters

        shape = param.shape
        ndim = param.ndimension()

        try:
            if ndim == 1:
                plot_1d(name, param, output_dir)
            elif ndim == 2:
                plot_2d(name, param, output_dir)
            elif ndim == 3:
                plot_3d(name, param, output_dir)
            elif ndim == 4:
                plot_4d(name, param, output_dir)
            elif ndim == 5:
                plot_5d(name, param, output_dir)
            else:
                print(f"Skipping parameter '{name}' with unsupported dimensions: {ndim}D")
        except Exception as e:
            print(f"Failed to plot parameter '{name}': {e}")

# Example Usage
if __name__ == "__main__":
    import torch.nn as nn
    from transformers import AutoModelForCausalLM
    # Instantiate the model
    model = AutoModelForCausalLM.from_pretrained("gpt2")
    visualize_model_parameters(model, output_dir="model_parameter_plots")