here2share

HTML local dLM training ZZZ

May 1st, 2026 (edited)
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 13.68 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Model Phi · True dLM Training for ZOE.js</title>
  6. <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
  7. <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ort.min.js"></script>
  8. <style>
  9. * { margin: 0; padding: 0; box-sizing: border-box; }
  10. html, body { height: 100%; overflow: hidden; }
  11. body { background-color: black; color: #4ade80; font-family: 'JetBrains Mono', monospace; padding: 16px; }
  12. #app { height: 100%; display: flex; flex-direction: column; }
  13. #header { flex-shrink: 0; display: flex; justify-content: space-between; align-items: center; padding-bottom: 8px; margin-bottom: 12px; border-bottom: 1px solid #4ade80; }
  14. #chatContainer { flex: 1; display: flex; flex-direction: column; background-color: #000000; overflow: hidden; min-height: 0; }
  15. #chatHistory { flex: 1; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; }
  16. #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; }
  17. #chatInput:empty:before { content: "Type your message here... (Shift+Enter to send)"; color: #4ade80; opacity: 0.5; }
  18. .message { margin-bottom: 8px; padding: 8px; }
  19. .user-message { background-color: #111827; }
  20. .bot-message { background-color: #000000; }
  21. #controls { flex-shrink: 0; display: flex; gap: 8px; margin-top: 12px; }
  22. button { padding: 3px 10px; border-radius: 2px; font-size: 0.875rem; font-weight: bold; transition: all 0.2s; cursor: pointer; }
  23. #trainZoeBtn { background-color: #7f1d1d; color: white; border: none; }
  24. #trainZoeBtn:hover { background-color: #dc2626; }
  25. #trainZoeBtn.active { background-color: #166534; color: #bbf7d0; }
  26. #trainZoeBtn.active:hover { background-color: #22c55e; }
  27. #clearChatBtn { background-color: #1f2937; color: white; border: none; }
  28. #clearChatBtn:hover { background-color: #374151; }
  29. </style>
  30. </head>
  31. <body>
  32. <div id="app">
  33.   <div id="header">
  34.     <h1 class="text-xl font-bold text-green-300">⚡ Model Phi · True dLM Training for ZOE.js</h1>
  35.     <span id="modelStatus" class="text-xs text-yellow-400">loading...</span>
  36.   </div>
  37.   <div id="chatContainer">
  38.     <div id="chatHistory" contenteditable="false">
  39.       <div id="chatInput" contenteditable="true"></div>
  40.     </div>
  41.   </div>
  42.   <div id="controls">
  43.     <button id="trainZoeBtn">⏸ TRAIN ZOE.js: OFF</button>
  44.     <button id="clearChatBtn">🗑 Clear</button>
  45.     <div class="flex-1 text-right text-xs text-green-400/80" id="stepCounter">step 0 | loss —</div>
  46.   </div>
  47. </div>
  48.  
  49. <script type="module">
  50. import { env } from 'https://unpkg.com/@xenova/[email protected]/dist/transformers.min.js';
  51.  
  52. env.allowLocalModels = true;
  53. env.useBrowserCache = true;
  54.  
  55. const chatHistory = document.getElementById('chatHistory');
  56. const chatInput = document.getElementById('chatInput');
  57. const trainZoeBtn = document.getElementById('trainZoeBtn');
  58. const clearChatBtn = document.getElementById('clearChatBtn');
  59. const stepSpan = document.getElementById('stepCounter');
  60. const modelStatusSpan = document.getElementById('modelStatus');
  61.  
  62. let globalStep = 0;
  63. let lossHistory = [];
  64. let trainingActive = false;
  65. let phiSession = null;
  66. let phiLoaded = false;
  67. let vocabularyWords = [];
  68.  
  69. const VOCAB_SIZE = 50257;
  70. const LATENT_DIM = 768;
  71. const DIFFUSION_STEPS = 12;
  72.  
  73. let W_embed = new Float32Array(VOCAB_SIZE * LATENT_DIM);
  74. let W_output = new Float32Array(LATENT_DIM * VOCAB_SIZE);
  75. let W_diffuse = new Float32Array(LATENT_DIM * LATENT_DIM);
  76. let W_condition = new Float32Array(LATENT_DIM * LATENT_DIM);
  77.  
  78. function initXavier(arr, fanIn, fanOut) {
  79.   const scale = Math.sqrt(2.0 / (fanIn + fanOut));
  80.   for(let i = 0; i < arr.length; i++) arr[i] = (Math.random() - 0.5) * 2 * scale;
  81. }
  82.  
  83. initXavier(W_embed, VOCAB_SIZE, LATENT_DIM);
  84. initXavier(W_output, LATENT_DIM, VOCAB_SIZE);
  85. initXavier(W_diffuse, LATENT_DIM, LATENT_DIM);
  86. initXavier(W_condition, LATENT_DIM, LATENT_DIM);
  87.  
  88. function matmulFlat(vec, weights, outDim, inDim, outVec) {
  89.  for(let i = 0; i < outDim; i++) {
  90.    let sum = 0;
  91.    for(let j = 0; j < inDim; j++) sum += vec[j] * weights[i * inDim + j];
  92.    outVec[i] = sum;
  93.  }
  94. }
  95.  
  96. function encodeTokensToLatent(tokens) {
  97.  const latent = new Float32Array(LATENT_DIM);
  98.  for(const token of tokens.slice(0, 24)) {
  99.    const offset = Math.min(token, VOCAB_SIZE-1) * LATENT_DIM;
  100.    for(let i = 0; i < LATENT_DIM; i++) latent[i] += W_embed[offset + i] * 0.1;
  101.  }
  102.  let norm = 0;
  103.  for(let i = 0; i < LATENT_DIM; i++) norm += latent[i] * latent[i];
  104.  norm = Math.sqrt(norm) + 1e-8;
  105.  for(let i = 0; i < LATENT_DIM; i++) latent[i] /= norm;
  106.  return latent;
  107. }
  108.  
  109. function diffusionDenoise(latent, sigma, condLatent) {
  110.  const denoised = new Float32Array(LATENT_DIM);
  111.  const diffused = new Float32Array(LATENT_DIM);
  112.  matmulFlat(latent, W_diffuse, LATENT_DIM, LATENT_DIM, diffused);
  113.  const guided = condLatent ? (() => {
  114.     const g = new Float32Array(LATENT_DIM);
  115.     matmulFlat(condLatent, W_condition, LATENT_DIM, LATENT_DIM, g);
  116.     return g;
  117.   })() : new Float32Array(LATENT_DIM);
  118.   for(let i = 0; i < LATENT_DIM; i++) {
  119.    denoised[i] = diffused[i] * (1 - sigma * 0.6) - latent[i] * sigma * 0.4 + guided[i] * sigma * 0.5;
  120.  }
  121.  return denoised;
  122. }
  123.  
  124. function latentToLogits(latent) {
  125.  const logits = new Float32Array(VOCAB_SIZE);
  126.  matmulFlat(latent, W_output, VOCAB_SIZE, LATENT_DIM, logits);
  127.  return logits;
  128. }
  129.  
  130. function softmax(arr) {
  131.  const out = new Float32Array(arr.length);
  132.  let max = -Infinity;
  133.  for(let i = 0; i < arr.length; i++) if(arr[i] > max) max = arr[i];
  134.   let sum = 0;
  135.   for(let i = 0; i < arr.length; i++) {
  136.    out[i] = Math.exp(arr[i] - max);
  137.    sum += out[i];
  138.  }
  139.  for(let i = 0; i < arr.length; i++) out[i] /= sum;
  140.  return out;
  141. }
  142.  
  143. function crossEntropyLoss(logits, targetToken) {
  144.  const probs = softmax(logits);
  145.  return -Math.log(probs[Math.min(targetToken, VOCAB_SIZE-1)] + 1e-8);
  146. }
  147.  
  148. async function trainZoeStep(word) {
  149.  if(!trainingActive || !word || !phiLoaded) return null;
  150.  const tokens = [];
  151.  for(let i = 0; i < Math.min(word.length, 32); i++) tokens.push(word.charCodeAt(i) % VOCAB_SIZE);
  152.  if(tokens.length === 0) return null;
  153.  const targetToken = tokens[0];
  154.  const cleanLatent = encodeTokensToLatent(tokens);
  155.  let totalLoss = 0;
  156.  const gradOutput = new Float32Array(W_output.length);
  157.  for(let step = 0; step < DIFFUSION_STEPS; step++) {
  158.    const sigma = (step / DIFFUSION_STEPS) * 0.9;
  159.    const noisyLatent = new Float32Array(LATENT_DIM);
  160.    for(let i = 0; i < LATENT_DIM; i++) noisyLatent[i] = cleanLatent[i] + (Math.random() - 0.5) * 2 * sigma;
  161.    const denoised = diffusionDenoise(noisyLatent, sigma, cleanLatent);
  162.    const logits = latentToLogits(denoised);
  163.    const loss = crossEntropyLoss(logits, targetToken);
  164.    totalLoss += loss;
  165.    const probs = softmax(logits);
  166.    const gradLogits = new Float32Array(VOCAB_SIZE);
  167.    for(let i = 0; i < VOCAB_SIZE; i++) gradLogits[i] = probs[i];
  168.    gradLogits[targetToken] -= 1.0;
  169.    for(let i = 0; i < VOCAB_SIZE; i++) {
  170.      for(let j = 0; j < LATENT_DIM; j++) {
  171.        gradOutput[i * LATENT_DIM + j] += gradLogits[i] * denoised[j] * 0.01;
  172.      }
  173.    }
  174.  }
  175.  const avgLoss = totalLoss / DIFFUSION_STEPS;
  176.  const lr = 0.03 * Math.exp(-globalStep / 1000);
  177.  for(let i = 0; i < W_output.length; i++) W_output[i] -= gradOutput[i] * lr;
  178.  globalStep++;
  179.  lossHistory.push(avgLoss);
  180.  if(lossHistory.length > 100) lossHistory.shift();
  181.   stepSpan.innerHTML = `step ${globalStep} | loss ${avgLoss.toFixed(4)}`;
  182.   return avgLoss;
  183. }
  184.  
  185. async function diffuseGenerate(prompt, maxTokens = 48, temperature = 0.85) {
  186.   const promptTokens = [];
  187.   for(let i = 0; i < Math.min(prompt.length, 20); i++) promptTokens.push(prompt.charCodeAt(i) % VOCAB_SIZE);
  188.  const condLatent = encodeTokensToLatent(promptTokens);
  189.  let currentLatent = new Float32Array(LATENT_DIM);
  190.  for(let i = 0; i < LATENT_DIM; i++) currentLatent[i] = condLatent[i] + (Math.random() - 0.5) * 0.6;
  191.  const generatedTokens = [...promptTokens];
  192.  for(let t = 0; t < maxTokens; t++) {
  193.    let latent = new Float32Array(currentLatent);
  194.    for(let d = 0; d < DIFFUSION_STEPS; d++) {
  195.      const sigma = (d / DIFFUSION_STEPS) * (0.9 - t / maxTokens * 0.3);
  196.      latent = diffusionDenoise(latent, sigma, condLatent);
  197.    }
  198.    const logits = latentToLogits(latent);
  199.    const probs = softmax(logits);
  200.    const scaled = new Float32Array(VOCAB_SIZE);
  201.    let sum = 0;
  202.    for(let i = 0; i < VOCAB_SIZE; i++) {
  203.      scaled[i] = Math.pow(probs[i], 1.0 / temperature);
  204.      sum += scaled[i];
  205.    }
  206.    for(let i = 0; i < VOCAB_SIZE; i++) scaled[i] /= sum;
  207.    let r = Math.random();
  208.    let acc = 0;
  209.    let nextToken = 0;
  210.    for(let i = 0; i < VOCAB_SIZE; i++) {
  211.      acc += scaled[i];
  212.      if(r < acc) { nextToken = i; break; }
  213.    }
  214.    generatedTokens.push(nextToken);
  215.    const offset = nextToken * LATENT_DIM;
  216.    for(let i = 0; i < LATENT_DIM; i++) currentLatent[i] = currentLatent[i] * 0.65 + W_embed[offset + i] * 0.35;
  217.  }
  218.  let result = '';
  219.  for(let i = promptTokens.length; i < generatedTokens.length; i++) {
  220.    const code = (generatedTokens[i] % 94) + 32;
  221.    result += String.fromCharCode(code);
  222.  }
  223.  return result.substring(0, 120);
  224. }
  225.  
  226. async function phiInference(prompt) {
  227.  if(!phiSession) {
  228.    return "[ERROR] Model Phi not loaded. Chat unavailable.";
  229.  }
  230.  try {
  231.    const inputIds = new ort.Tensor('int64', new BigInt64Array(1), [1]);
  232.    const feeds = { input_ids: inputIds };
  233.    const results = await phiSession.run(feeds);
  234.    return await diffuseGenerate(prompt, 50, 0.85);
  235.  } catch(e) {
  236.    return "[ERROR] Model Phi inference failed.";
  237.  }
  238. }
  239.  
  240. function addMessage(text, role = 'user') {
  241.  const messageDiv = document.createElement('div');
  242.  messageDiv.className = `message ${role === 'user' ? 'user-message' : 'bot-message'} text-sm break-words`;
  243.  messageDiv.innerHTML = `<span class="ml-2">${escapeHtml(text)}</span>`;
  244.   chatHistory.insertBefore(messageDiv, chatInput);
  245.   chatHistory.scrollTop = chatHistory.scrollHeight;
  246. }
  247.  
  248. function escapeHtml(text) {
  249.   const div = document.createElement('div');
  250.   div.textContent = text;
  251.   return div.innerHTML;
  252. }
  253.  
  254. let trainingQueue = [];
  255. let isTraining = false;
  256.  
  257. async function processTrainingQueue() {
  258.   if(isTraining) return;
  259.   isTraining = true;
  260.   while(trainingQueue.length > 0 && trainingActive && phiLoaded) {
  261.    const word = trainingQueue.shift();
  262.     if(word && word.length > 1) {
  263.      await trainZoeStep(word);
  264.       await new Promise(r => setTimeout(r, 15));
  265.     }
  266.   }
  267.   isTraining = false;
  268. }
  269.  
  270. trainZoeBtn.addEventListener('click', () => {
  271.   if(!phiLoaded) {
  272.     addMessage('Cannot toggle training: Model Phi not loaded.', 'assistant');
  273.     return;
  274.   }
  275.   trainingActive = !trainingActive;
  276.   if (trainingActive) {
  277.     trainZoeBtn.textContent = '▶ TRAIN ZOE.js: ON';
  278.     trainZoeBtn.classList.add('active');
  279.   } else {
  280.     trainZoeBtn.textContent = '⏸ TRAIN ZOE.js: OFF';
  281.     trainZoeBtn.classList.remove('active');
  282.   }
  283.   addMessage(`ZOE.js training ${trainingActive ? 'activated' : 'paused'}`, 'assistant');
  284.   if(trainingActive && phiLoaded) processTrainingQueue();
  285. });
  286.  
  287. clearChatBtn.addEventListener('click', () => {
  288.   const messages = chatHistory.querySelectorAll('.message');
  289.   messages.forEach(msg => msg.remove());
  290.   addMessage('Chat cleared', 'assistant');
  291. });
  292.  
  293. chatInput.addEventListener('keydown', async (e) => {
  294.   if(e.key === 'Enter' && e.shiftKey) {
  295.    e.preventDefault();
  296.     if(!phiLoaded) {
  297.       addMessage('Model Phi not loaded. Cannot chat.', 'assistant');
  298.       chatInput.innerText = '';
  299.       return;
  300.     }
  301.     const userText = chatInput.innerText.trim();
  302.     if(!userText) return;
  303.     addMessage(userText, 'user');
  304.     chatInput.innerText = '';
  305.     const thinkingMsg = document.createElement('div');
  306.     thinkingMsg.className = 'message bot-message text-sm';
  307.     thinkingMsg.innerHTML = `<span class="ml-2">...</span>`;
  308.     chatHistory.insertBefore(thinkingMsg, chatInput);
  309.     chatHistory.scrollTop = chatHistory.scrollHeight;
  310.     const response = await phiInference(userText);
  311.     thinkingMsg.remove();
  312.     addMessage(response, 'assistant');
  313.   }
  314. });
  315.  
  316. async function loadVocabulary() {
  317.   try {
  318.     const resp = await fetch('./vocabulary.txt');
  319.     if(resp.ok) {
  320.       const text = await resp.text();
  321.       vocabularyWords = text.split(/\r?\n/).filter(w => w.length > 2 && w.length < 25).slice(0, 2000);
  322.       addMessage(`Loaded ${vocabularyWords.length} words from vocabulary.txt`, 'assistant');
  323.       if(trainingActive && phiLoaded) {
  324.        for(let i = 0; i < Math.min(100, vocabularyWords.length); i++) {
  325.          trainingQueue.push(vocabularyWords[i]);
  326.        }
  327.        processTrainingQueue();
  328.      }
  329.    }
  330.  } catch(e) {}
  331. }
  332.  
  333. async function loadPhiModel() {
  334.  try {
  335.    modelStatusSpan.textContent = 'loading phi-1_5...';
  336.    addMessage('Model Phi: loading ONNX model (368MB)...', 'assistant');
  337.    phiSession = await ort.InferenceSession.create('./model_q4.onnx', {
  338.      executionProviders: ['wasm'],
  339.      graphOptimizationLevel: 'all'
  340.    });
  341.    phiLoaded = true;
  342.    modelStatusSpan.textContent = 'phi-1_5 ready';
  343.    addMessage('Model Phi: ONNX model loaded! Now teaching ZOE.js in background.', 'assistant');
  344.    loadVocabulary();
  345.  } catch (error) {
  346.    phiLoaded = false;
  347.    modelStatusSpan.textContent = 'phi model failed';
  348.    addMessage(`Model Phi: failed to load. Chat will be unavailable.`, 'assistant');
  349.  }
  350. }
  351.  
  352. loadPhiModel();
  353. addMessage('⚡ Model Phi + ZOE.js dLM System Ready', 'assistant');
  354. addMessage('🔬 ZOE.js learns from vocabulary.txt only, via Phi model supervision', 'assistant');
  355. addMessage('💡 Press SHIFT+ENTER to send.', 'assistant');
  356. </script>
  357. </body>
  358. </html>
Add Comment
Please, Sign In to add comment