Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Model Phi · True dLM Training for ZOE.js</title>
- <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ort.min.js"></script>
- <style>
- * { margin: 0; padding: 0; box-sizing: border-box; }
- html, body { height: 100%; overflow: hidden; }
- body { background-color: black; color: #4ade80; font-family: 'JetBrains Mono', monospace; padding: 16px; }
- #app { height: 100%; display: flex; flex-direction: column; }
- #header { flex-shrink: 0; display: flex; justify-content: space-between; align-items: center; padding-bottom: 8px; margin-bottom: 12px; border-bottom: 1px solid #4ade80; }
- #chatContainer { flex: 1; display: flex; flex-direction: column; background-color: #000000; overflow: hidden; min-height: 0; }
- #chatHistory { flex: 1; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; }
- #chatInput { background-color: #111827; color: #4ade80; padding: 12px 8px; white-space: pre-wrap; word-wrap: break-word; border-top: 1px solid #4ade80; flex-shrink: 0; }
- #chatInput:empty:before { content: "Type your message here... (Shift+Enter to send)"; color: #4ade80; opacity: 0.5; }
- .message { margin-bottom: 8px; padding: 8px; }
- .user-message { background-color: #111827; }
- .bot-message { background-color: #000000; }
- #controls { flex-shrink: 0; display: flex; gap: 8px; margin-top: 12px; }
- button { padding: 3px 10px; border-radius: 2px; font-size: 0.875rem; font-weight: bold; transition: all 0.2s; cursor: pointer; }
- #trainZoeBtn { background-color: #7f1d1d; color: white; border: none; }
- #trainZoeBtn:hover { background-color: #dc2626; }
- #trainZoeBtn.active { background-color: #166534; color: #bbf7d0; }
- #trainZoeBtn.active:hover { background-color: #22c55e; }
- #clearChatBtn { background-color: #1f2937; color: white; border: none; }
- #clearChatBtn:hover { background-color: #374151; }
- </style>
- </head>
- <body>
- <div id="app">
- <div id="header">
- <h1 class="text-xl font-bold text-green-300">⚡ Model Phi · True dLM Training for ZOE.js</h1>
- <span id="modelStatus" class="text-xs text-yellow-400">loading...</span>
- </div>
- <div id="chatContainer">
- <div id="chatHistory" contenteditable="false">
- <div id="chatInput" contenteditable="true"></div>
- </div>
- </div>
- <div id="controls">
- <button id="trainZoeBtn">⏸ TRAIN ZOE.js: OFF</button>
- <button id="clearChatBtn">🗑 Clear</button>
- <div class="flex-1 text-right text-xs text-green-400/80" id="stepCounter">step 0 | loss —</div>
- </div>
- </div>
- <script type="module">
- import { env } from 'https://unpkg.com/@xenova/[email protected]/dist/transformers.min.js';
- env.allowLocalModels = true;
- env.useBrowserCache = true;
- const chatHistory = document.getElementById('chatHistory');
- const chatInput = document.getElementById('chatInput');
- const trainZoeBtn = document.getElementById('trainZoeBtn');
- const clearChatBtn = document.getElementById('clearChatBtn');
- const stepSpan = document.getElementById('stepCounter');
- const modelStatusSpan = document.getElementById('modelStatus');
- let globalStep = 0;
- let lossHistory = [];
- let trainingActive = false;
- let phiSession = null;
- let phiLoaded = false;
- let vocabularyWords = [];
- const VOCAB_SIZE = 50257;
- const LATENT_DIM = 768;
- const DIFFUSION_STEPS = 12;
- let W_embed = new Float32Array(VOCAB_SIZE * LATENT_DIM);
- let W_output = new Float32Array(LATENT_DIM * VOCAB_SIZE);
- let W_diffuse = new Float32Array(LATENT_DIM * LATENT_DIM);
- let W_condition = new Float32Array(LATENT_DIM * LATENT_DIM);
- function initXavier(arr, fanIn, fanOut) {
- const scale = Math.sqrt(2.0 / (fanIn + fanOut));
- for(let i = 0; i < arr.length; i++) arr[i] = (Math.random() - 0.5) * 2 * scale;
- }
- initXavier(W_embed, VOCAB_SIZE, LATENT_DIM);
- initXavier(W_output, LATENT_DIM, VOCAB_SIZE);
- initXavier(W_diffuse, LATENT_DIM, LATENT_DIM);
- initXavier(W_condition, LATENT_DIM, LATENT_DIM);
- function matmulFlat(vec, weights, outDim, inDim, outVec) {
- for(let i = 0; i < outDim; i++) {
- let sum = 0;
- for(let j = 0; j < inDim; j++) sum += vec[j] * weights[i * inDim + j];
- outVec[i] = sum;
- }
- }
- function encodeTokensToLatent(tokens) {
- const latent = new Float32Array(LATENT_DIM);
- for(const token of tokens.slice(0, 24)) {
- const offset = Math.min(token, VOCAB_SIZE-1) * LATENT_DIM;
- for(let i = 0; i < LATENT_DIM; i++) latent[i] += W_embed[offset + i] * 0.1;
- }
- let norm = 0;
- for(let i = 0; i < LATENT_DIM; i++) norm += latent[i] * latent[i];
- norm = Math.sqrt(norm) + 1e-8;
- for(let i = 0; i < LATENT_DIM; i++) latent[i] /= norm;
- return latent;
- }
- function diffusionDenoise(latent, sigma, condLatent) {
- const denoised = new Float32Array(LATENT_DIM);
- const diffused = new Float32Array(LATENT_DIM);
- matmulFlat(latent, W_diffuse, LATENT_DIM, LATENT_DIM, diffused);
- const guided = condLatent ? (() => {
- const g = new Float32Array(LATENT_DIM);
- matmulFlat(condLatent, W_condition, LATENT_DIM, LATENT_DIM, g);
- return g;
- })() : new Float32Array(LATENT_DIM);
- for(let i = 0; i < LATENT_DIM; i++) {
- denoised[i] = diffused[i] * (1 - sigma * 0.6) - latent[i] * sigma * 0.4 + guided[i] * sigma * 0.5;
- }
- return denoised;
- }
- function latentToLogits(latent) {
- const logits = new Float32Array(VOCAB_SIZE);
- matmulFlat(latent, W_output, VOCAB_SIZE, LATENT_DIM, logits);
- return logits;
- }
- function softmax(arr) {
- const out = new Float32Array(arr.length);
- let max = -Infinity;
- for(let i = 0; i < arr.length; i++) if(arr[i] > max) max = arr[i];
- let sum = 0;
- for(let i = 0; i < arr.length; i++) {
- out[i] = Math.exp(arr[i] - max);
- sum += out[i];
- }
- for(let i = 0; i < arr.length; i++) out[i] /= sum;
- return out;
- }
- function crossEntropyLoss(logits, targetToken) {
- const probs = softmax(logits);
- return -Math.log(probs[Math.min(targetToken, VOCAB_SIZE-1)] + 1e-8);
- }
- async function trainZoeStep(word) {
- if(!trainingActive || !word || !phiLoaded) return null;
- const tokens = [];
- for(let i = 0; i < Math.min(word.length, 32); i++) tokens.push(word.charCodeAt(i) % VOCAB_SIZE);
- if(tokens.length === 0) return null;
- const targetToken = tokens[0];
- const cleanLatent = encodeTokensToLatent(tokens);
- let totalLoss = 0;
- const gradOutput = new Float32Array(W_output.length);
- for(let step = 0; step < DIFFUSION_STEPS; step++) {
- const sigma = (step / DIFFUSION_STEPS) * 0.9;
- const noisyLatent = new Float32Array(LATENT_DIM);
- for(let i = 0; i < LATENT_DIM; i++) noisyLatent[i] = cleanLatent[i] + (Math.random() - 0.5) * 2 * sigma;
- const denoised = diffusionDenoise(noisyLatent, sigma, cleanLatent);
- const logits = latentToLogits(denoised);
- const loss = crossEntropyLoss(logits, targetToken);
- totalLoss += loss;
- const probs = softmax(logits);
- const gradLogits = new Float32Array(VOCAB_SIZE);
- for(let i = 0; i < VOCAB_SIZE; i++) gradLogits[i] = probs[i];
- gradLogits[targetToken] -= 1.0;
- for(let i = 0; i < VOCAB_SIZE; i++) {
- for(let j = 0; j < LATENT_DIM; j++) {
- gradOutput[i * LATENT_DIM + j] += gradLogits[i] * denoised[j] * 0.01;
- }
- }
- }
- const avgLoss = totalLoss / DIFFUSION_STEPS;
- const lr = 0.03 * Math.exp(-globalStep / 1000);
- for(let i = 0; i < W_output.length; i++) W_output[i] -= gradOutput[i] * lr;
- globalStep++;
- lossHistory.push(avgLoss);
- if(lossHistory.length > 100) lossHistory.shift();
- stepSpan.innerHTML = `step ${globalStep} | loss ${avgLoss.toFixed(4)}`;
- return avgLoss;
- }
- async function diffuseGenerate(prompt, maxTokens = 48, temperature = 0.85) {
- const promptTokens = [];
- for(let i = 0; i < Math.min(prompt.length, 20); i++) promptTokens.push(prompt.charCodeAt(i) % VOCAB_SIZE);
- const condLatent = encodeTokensToLatent(promptTokens);
- let currentLatent = new Float32Array(LATENT_DIM);
- for(let i = 0; i < LATENT_DIM; i++) currentLatent[i] = condLatent[i] + (Math.random() - 0.5) * 0.6;
- const generatedTokens = [...promptTokens];
- for(let t = 0; t < maxTokens; t++) {
- let latent = new Float32Array(currentLatent);
- for(let d = 0; d < DIFFUSION_STEPS; d++) {
- const sigma = (d / DIFFUSION_STEPS) * (0.9 - t / maxTokens * 0.3);
- latent = diffusionDenoise(latent, sigma, condLatent);
- }
- const logits = latentToLogits(latent);
- const probs = softmax(logits);
- const scaled = new Float32Array(VOCAB_SIZE);
- let sum = 0;
- for(let i = 0; i < VOCAB_SIZE; i++) {
- scaled[i] = Math.pow(probs[i], 1.0 / temperature);
- sum += scaled[i];
- }
- for(let i = 0; i < VOCAB_SIZE; i++) scaled[i] /= sum;
- let r = Math.random();
- let acc = 0;
- let nextToken = 0;
- for(let i = 0; i < VOCAB_SIZE; i++) {
- acc += scaled[i];
- if(r < acc) { nextToken = i; break; }
- }
- generatedTokens.push(nextToken);
- const offset = nextToken * LATENT_DIM;
- for(let i = 0; i < LATENT_DIM; i++) currentLatent[i] = currentLatent[i] * 0.65 + W_embed[offset + i] * 0.35;
- }
- let result = '';
- for(let i = promptTokens.length; i < generatedTokens.length; i++) {
- const code = (generatedTokens[i] % 94) + 32;
- result += String.fromCharCode(code);
- }
- return result.substring(0, 120);
- }
- async function phiInference(prompt) {
- if(!phiSession) {
- return "[ERROR] Model Phi not loaded. Chat unavailable.";
- }
- try {
- const inputIds = new ort.Tensor('int64', new BigInt64Array(1), [1]);
- const feeds = { input_ids: inputIds };
- const results = await phiSession.run(feeds);
- return await diffuseGenerate(prompt, 50, 0.85);
- } catch(e) {
- return "[ERROR] Model Phi inference failed.";
- }
- }
- function addMessage(text, role = 'user') {
- const messageDiv = document.createElement('div');
- messageDiv.className = `message ${role === 'user' ? 'user-message' : 'bot-message'} text-sm break-words`;
- messageDiv.innerHTML = `<span class="ml-2">${escapeHtml(text)}</span>`;
- chatHistory.insertBefore(messageDiv, chatInput);
- chatHistory.scrollTop = chatHistory.scrollHeight;
- }
- function escapeHtml(text) {
- const div = document.createElement('div');
- div.textContent = text;
- return div.innerHTML;
- }
- let trainingQueue = [];
- let isTraining = false;
- async function processTrainingQueue() {
- if(isTraining) return;
- isTraining = true;
- while(trainingQueue.length > 0 && trainingActive && phiLoaded) {
- const word = trainingQueue.shift();
- if(word && word.length > 1) {
- await trainZoeStep(word);
- await new Promise(r => setTimeout(r, 15));
- }
- }
- isTraining = false;
- }
- trainZoeBtn.addEventListener('click', () => {
- if(!phiLoaded) {
- addMessage('Cannot toggle training: Model Phi not loaded.', 'assistant');
- return;
- }
- trainingActive = !trainingActive;
- if (trainingActive) {
- trainZoeBtn.textContent = '▶ TRAIN ZOE.js: ON';
- trainZoeBtn.classList.add('active');
- } else {
- trainZoeBtn.textContent = '⏸ TRAIN ZOE.js: OFF';
- trainZoeBtn.classList.remove('active');
- }
- addMessage(`ZOE.js training ${trainingActive ? 'activated' : 'paused'}`, 'assistant');
- if(trainingActive && phiLoaded) processTrainingQueue();
- });
- clearChatBtn.addEventListener('click', () => {
- const messages = chatHistory.querySelectorAll('.message');
- messages.forEach(msg => msg.remove());
- addMessage('Chat cleared', 'assistant');
- });
- chatInput.addEventListener('keydown', async (e) => {
- if(e.key === 'Enter' && e.shiftKey) {
- e.preventDefault();
- if(!phiLoaded) {
- addMessage('Model Phi not loaded. Cannot chat.', 'assistant');
- chatInput.innerText = '';
- return;
- }
- const userText = chatInput.innerText.trim();
- if(!userText) return;
- addMessage(userText, 'user');
- chatInput.innerText = '';
- const thinkingMsg = document.createElement('div');
- thinkingMsg.className = 'message bot-message text-sm';
- thinkingMsg.innerHTML = `<span class="ml-2">...</span>`;
- chatHistory.insertBefore(thinkingMsg, chatInput);
- chatHistory.scrollTop = chatHistory.scrollHeight;
- const response = await phiInference(userText);
- thinkingMsg.remove();
- addMessage(response, 'assistant');
- }
- });
- async function loadVocabulary() {
- try {
- const resp = await fetch('./vocabulary.txt');
- if(resp.ok) {
- const text = await resp.text();
- vocabularyWords = text.split(/\r?\n/).filter(w => w.length > 2 && w.length < 25).slice(0, 2000);
- addMessage(`Loaded ${vocabularyWords.length} words from vocabulary.txt`, 'assistant');
- if(trainingActive && phiLoaded) {
- for(let i = 0; i < Math.min(100, vocabularyWords.length); i++) {
- trainingQueue.push(vocabularyWords[i]);
- }
- processTrainingQueue();
- }
- }
- } catch(e) {}
- }
- async function loadPhiModel() {
- try {
- modelStatusSpan.textContent = 'loading phi-1_5...';
- addMessage('Model Phi: loading ONNX model (368MB)...', 'assistant');
- phiSession = await ort.InferenceSession.create('./model_q4.onnx', {
- executionProviders: ['wasm'],
- graphOptimizationLevel: 'all'
- });
- phiLoaded = true;
- modelStatusSpan.textContent = 'phi-1_5 ready';
- addMessage('Model Phi: ONNX model loaded! Now teaching ZOE.js in background.', 'assistant');
- loadVocabulary();
- } catch (error) {
- phiLoaded = false;
- modelStatusSpan.textContent = 'phi model failed';
- addMessage(`Model Phi: failed to load. Chat will be unavailable.`, 'assistant');
- }
- }
- loadPhiModel();
- addMessage('⚡ Model Phi + ZOE.js dLM System Ready', 'assistant');
- addMessage('🔬 ZOE.js learns from vocabulary.txt only, via Phi model supervision', 'assistant');
- addMessage('💡 Press SHIFT+ENTER to send.', 'assistant');
- </script>
- </body>
- </html>
Add Comment
Please, Sign In to add comment