llm-size-compare / index.html
fredmo's picture
Update index.html
a95ac7f verified
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transformer Matrix Visualization - Aligned</title>
<style>
body {
margin: 0;
font-family: 'Segoe UI', 'Roboto', 'Oxygen', sans-serif;
background-color: #000000;
color: #e0e0e0;
overflow: hidden;
}
#button-container {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
display: flex;
gap: 15px;
background-color: rgba(10, 10, 10, 0.7);
padding: 10px 20px;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.focus-btn {
background-color: #222;
color: #ddd;
border: 1px solid #444;
padding: 8px 16px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: background-color 0.3s, color 0.3s;
}
.focus-btn:hover {
background-color: #0077be;
color: #fff;
}
#tooltip {
position: absolute;
display: none;
padding: 12px;
background-color: rgba(10, 10, 25, 0.9);
border: 1px solid #0077be;
border-radius: 8px;
pointer-events: none;
font-size: 14px;
z-index: 101;
}
#tooltip h3 { margin: 0 0 8px 0; color: #8ac8ff; }
#tooltip p { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<div id="button-container"></div>
<div id="tooltip"></div>
<div id="canvas-container"></div>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.165.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.165.0/examples/jsm/",
"gsap": "https://unpkg.com/gsap@3.12.5/index.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { gsap } from 'gsap';
// --- Scene Setup ---
const scene = new THREE.Scene();
const container = document.getElementById('canvas-container');
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 200000);
camera.position.set(0, 200, 1500);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
const gridHelper = new THREE.GridHelper(400000, 400, 0x333333, 0x222222);
scene.add(gridHelper);
// This group will hold all models to make centering easy
const allModelsGroup = new THREE.Group();
scene.add(allModelsGroup);
const models = [];
const collidableObjects = [];
const colorPalette = [
new THREE.Color(0x6a0dad), new THREE.Color(0x0077be),
new THREE.Color(0x00a896), new THREE.Color(0xdc3958),
new THREE.Color(0xf7ac3d),
];
function createMatrixModel(name, params) {
const modelGroup = new THREE.Group();
const representativeCount = Math.floor(Math.max(400, params / 2e6));
const gridSide = Math.floor(Math.sqrt(representativeCount));
const instanceCount = gridSide * gridSide;
const squareSize = 5;
const modelWidth = gridSide * squareSize;
const geometry = new THREE.PlaneGeometry(squareSize * 0.9, squareSize * 0.9);
const material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide });
const mesh = new THREE.InstancedMesh(geometry, material, instanceCount);
const dummy = new THREE.Object3D();
let i = 0;
for (let x = 0; x < gridSide; x++) {
for (let y = 0; y < gridSide; y++) {
dummy.position.set(
(x - gridSide / 2) * squareSize,
(y - gridSide / 2) * squareSize,
0
);
dummy.updateMatrix();
mesh.setMatrixAt(i, dummy.matrix);
const color = colorPalette[Math.floor(Math.random() * colorPalette.length)];
mesh.setColorAt(i, color);
i++;
}
}
mesh.instanceMatrix.needsUpdate = true;
mesh.instanceColor.needsUpdate = true;
modelGroup.add(mesh);
modelGroup.userData = { name, params };
mesh.userData = { modelName: name, params };
models.push({ name, group: modelGroup, params });
collidableObjects.push(mesh);
// Return the group and its calculated width for layout purposes
return { modelGroup, modelWidth };
}
// --- NEW: Ordered Model Definitions & Linear Layout ---
const modelDefinitions = [
{ name: '1000B', params: 1000e9 }, { name: '405B', params: 405e9 },
{ name: '70B', params: 70e9 }, { name: '4B', params: 4e9 },
{ name: '1B', params: 1e9 }, { name: '0.2B', params: 0.2e9 },
];
let currentX = 0;
modelDefinitions.forEach((def) => {
const { modelGroup, modelWidth } = createMatrixModel(def.name, def.params);
// Add padding based on the size of the model
const padding = modelWidth * 0.5;
// Position the model along the X axis
modelGroup.position.x = currentX + modelWidth / 2;
// Add the model to the main group
allModelsGroup.add(modelGroup);
// Update the X-coordinate for the next model
currentX += modelWidth + padding;
});
// Center the entire line of models at the world origin
const sceneBox = new THREE.Box3().setFromObject(allModelsGroup);
const sceneCenter = new THREE.Vector3();
sceneBox.getCenter(sceneCenter);
allModelsGroup.position.x = -sceneCenter.x;
// --- UI and Camera Control ---
const buttonContainer = document.getElementById('button-container');
models.forEach(model => {
const btn = document.createElement('button');
btn.className = 'focus-btn';
btn.innerText = model.name;
btn.onclick = () => focusOnModel(model);
buttonContainer.appendChild(btn);
});
function focusOnModel(model) {
const modelWorldPosition = new THREE.Vector3();
model.group.getWorldPosition(modelWorldPosition);
const modelBox = new THREE.Box3().setFromObject(model.group);
const modelSize = new THREE.Vector3();
modelBox.getSize(modelSize);
const cameraDistance = modelSize.y / (2 * Math.tan(camera.fov * Math.PI / 360)) * 1.5; // Frame based on height
const cameraZ = Math.max(cameraDistance, modelSize.x); // Ensure we are far enough to see the width
const cameraTargetPosition = new THREE.Vector3(
modelWorldPosition.x,
modelWorldPosition.y,
modelWorldPosition.z + cameraZ
);
gsap.to(camera.position, {
x: cameraTargetPosition.x,
y: cameraTargetPosition.y,
z: cameraTargetPosition.z,
duration: 2.5,
ease: 'power3.inOut'
});
gsap.to(controls.target, {
x: modelWorldPosition.x,
y: modelWorldPosition.y,
z: modelWorldPosition.z,
duration: 2.5,
ease: 'power3.inOut'
});
}
// --- Interactivity & Render Loop ---
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const tooltip = document.getElementById('tooltip');
window.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
tooltip.style.left = (event.clientX + 15) + 'px';
tooltip.style.top = (event.clientY + 15) + 'px';
});
function animate() {
requestAnimationFrame(animate);
controls.update();
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(collidableObjects);
if (intersects.length > 0) {
const data = intersects[0].object.userData;
tooltip.style.display = 'block';
tooltip.innerHTML = `
<h3>${data.modelName} Model</h3>
<p><strong>Parameters:</strong> ${data.params.toLocaleString()}</p>
`;
} else {
tooltip.style.display = 'none';
}
renderer.render(scene, camera);
}
// Focus on the first model (1000B) to start
if (models.length > 0) {
focusOnModel(models[0]);
}
animate();
</script>
<footer>fredmo - 2025 </footer>
</body>
</html>