Download index.html from firobeid/LanguageModels_Decoding_Strategies_Demo: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/spaces/firobeid/LanguageModels_Decoding_Strategies_Demo/resolve/main/index.html
- Command line
-
hf download hf://spaces/firobeid/LanguageModels_Decoding_Strategies_Demo/index.html
-
curl -L -o index.html https://huggingface.co/spaces/firobeid/LanguageModels_Decoding_Strategies_Demo/resolve/main/index.html
13.2 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>LLM Decoding Strategies Demo</title> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| } | |
| .container { | |
| background: white; | |
| border-radius: 15px; | |
| padding: 30px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.2); | |
| } | |
| h1 { | |
| text-align: center; | |
| color: #333; | |
| margin-bottom: 30px; | |
| font-size: 2.5em; | |
| } | |
| .vocab-section { | |
| background: #f8f9fa; | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-bottom: 30px; | |
| border-left: 5px solid #667eea; | |
| } | |
| .logits-section { | |
| background: #e3f2fd; | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-bottom: 30px; | |
| border-left: 5px solid #2196f3; | |
| } | |
| .strategy { | |
| background: #fff; | |
| border: 2px solid #e0e0e0; | |
| border-radius: 10px; | |
| padding: 20px; | |
| margin-bottom: 20px; | |
| transition: all 0.3s ease; | |
| } | |
| .strategy:hover { | |
| border-color: #667eea; | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.1); | |
| } | |
| .strategy h3 { | |
| color: #667eea; | |
| margin-bottom: 15px; | |
| font-size: 1.4em; | |
| } | |
| .probs-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin: 15px 0; | |
| font-size: 0.9em; | |
| } | |
| .probs-table th, .probs-table td { | |
| padding: 8px 12px; | |
| border: 1px solid #ddd; | |
| text-align: center; | |
| } | |
| .probs-table th { | |
| background: #667eea; | |
| color: white; | |
| } | |
| .probs-table tr:nth-child(even) { | |
| background: #f9f9f9; | |
| } | |
| .selected { | |
| background: #4caf50 ; | |
| color: white; | |
| font-weight: bold; | |
| } | |
| .filtered { | |
| background: #ffcdd2 ; | |
| color: #666; | |
| } | |
| .result { | |
| background: #e8f5e8; | |
| padding: 15px; | |
| border-radius: 8px; | |
| margin-top: 15px; | |
| border-left: 4px solid #4caf50; | |
| } | |
| .controls { | |
| background: #f5f5f5; | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .control-group { | |
| margin-bottom: 15px; | |
| } | |
| .control-group label { | |
| display: inline-block; | |
| width: 120px; | |
| font-weight: bold; | |
| } | |
| .control-group input { | |
| padding: 5px; | |
| border: 1px solid #ddd; | |
| border-radius: 4px; | |
| width: 100px; | |
| } | |
| button { | |
| background: #667eea; | |
| color: white; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| font-size: 16px; | |
| transition: background 0.3s; | |
| } | |
| button:hover { | |
| background: #5a67d8; | |
| } | |
| .logits-display { | |
| font-family: monospace; | |
| font-size: 1.1em; | |
| background: #f0f0f0; | |
| padding: 10px; | |
| border-radius: 5px; | |
| margin: 10px 0; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>🤖 LLM Decoding Strategies Demo</h1> | |
| <div class="vocab-section"> | |
| <h2>📚 Vocabulary</h2> | |
| <p><strong>Tokens:</strong> ["the", "cat", "dog", "runs", "jumps", "quickly", ".", "and"]</p> | |
| <p><strong>Indices:</strong> [0, 1, 2, 3, 4, 5, 6, 7]</p> | |
| </div> | |
| <div class="controls"> | |
| <h2>🎛️ Controls</h2> | |
| <div class="control-group"> | |
| <label>Temperature:</label> | |
| <input type="number" id="temperature" value="1.0" step="0.1" min="0.1" max="3.0"> | |
| </div> | |
| <div class="control-group"> | |
| <label>Top-k:</label> | |
| <input type="number" id="topk" value="3" min="1" max="8"> | |
| </div> | |
| <div class="control-group"> | |
| <label>Top-p:</label> | |
| <input type="number" id="topp" value="0.8" step="0.1" min="0.1" max="1.0"> | |
| </div> | |
| <button onclick="generateNewLogits()">🎲 Generate New Logits</button> | |
| </div> | |
| <div class="logits-section"> | |
| <h2>📊 Current Logits</h2> | |
| <div id="logits-display" class="logits-display"></div> | |
| </div> | |
| <div id="strategies-container"></div> | |
| </div> | |
| <script> | |
| const vocab = ["the", "cat", "dog", "runs", "jumps", "quickly", ".", "and"]; | |
| let currentLogits = []; | |
| function generateRandomLogits() { | |
| return Array.from({length: 8}, () => (Math.random() - 0.5) * 6); | |
| } | |
| function softmax(logits, temperature = 1.0) { | |
| const scaledLogits = logits.map(x => x / temperature); | |
| const maxLogit = Math.max(...scaledLogits); | |
| const expLogits = scaledLogits.map(x => Math.exp(x - maxLogit)); | |
| const sumExp = expLogits.reduce((a, b) => a + b, 0); | |
| return expLogits.map(x => x / sumExp); | |
| } | |
| function greedyDecoding(logits) { | |
| const probs = softmax(logits); | |
| const maxIndex = probs.indexOf(Math.max(...probs)); | |
| return { | |
| selectedToken: vocab[maxIndex], | |
| selectedIndex: maxIndex, | |
| probs: probs, | |
| method: "Selected highest probability token" | |
| }; | |
| } | |
| function temperatureSampling(logits, temperature) { | |
| const probs = softmax(logits, temperature); | |
| const selectedIndex = sampleFromDistribution(probs); | |
| return { | |
| selectedToken: vocab[selectedIndex], | |
| selectedIndex: selectedIndex, | |
| probs: probs, | |
| method: `Temperature = ${temperature}, then sampled` | |
| }; | |
| } | |
| function topKSampling(logits, k) { | |
| const probs = softmax(logits); | |
| const indexed = probs.map((p, i) => ({prob: p, index: i})); | |
| indexed.sort((a, b) => b.prob - a.prob); | |
| const topK = indexed.slice(0, k); | |
| const topKProbs = new Array(vocab.length).fill(0); | |
| const sumTopK = topK.reduce((sum, item) => sum + item.prob, 0); | |
| topK.forEach(item => { | |
| topKProbs[item.index] = item.prob / sumTopK; | |
| }); | |
| const selectedIndex = sampleFromDistribution(topKProbs); | |
| return { | |
| selectedToken: vocab[selectedIndex], | |
| selectedIndex: selectedIndex, | |
| probs: topKProbs, | |
| originalProbs: probs, | |
| method: `Filtered to top-${k} tokens, then sampled` | |
| }; | |
| } | |
| function topPSampling(logits, p) { | |
| const probs = softmax(logits); | |
| const indexed = probs.map((prob, i) => ({prob, index: i})); | |
| indexed.sort((a, b) => b.prob - a.prob); | |
| let cumSum = 0; | |
| let cutoff = 0; | |
| for (let i = 0; i < indexed.length; i++) { | |
| cumSum += indexed[i].prob; | |
| if (cumSum >= p) { | |
| cutoff = i + 1; | |
| break; | |
| } | |
| } | |
| const nucleus = indexed.slice(0, cutoff); | |
| const nucleusProbs = new Array(vocab.length).fill(0); | |
| const sumNucleus = nucleus.reduce((sum, item) => sum + item.prob, 0); | |
| nucleus.forEach(item => { | |
| nucleusProbs[item.index] = item.prob / sumNucleus; | |
| }); | |
| const selectedIndex = sampleFromDistribution(nucleusProbs); | |
| return { | |
| selectedToken: vocab[selectedIndex], | |
| selectedIndex: selectedIndex, | |
| probs: nucleusProbs, | |
| originalProbs: probs, | |
| method: `Nucleus sampling with p=${p} (${cutoff} tokens)` | |
| }; | |
| } | |
| function sampleFromDistribution(probs) { | |
| const r = Math.random(); | |
| let cumSum = 0; | |
| for (let i = 0; i < probs.length; i++) { | |
| cumSum += probs[i]; | |
| if (r <= cumSum) { | |
| return i; | |
| } | |
| } | |
| return probs.length - 1; | |
| } | |
| function createProbabilityTable(probs, selectedIndex, originalProbs = null, title = "Probabilities") { | |
| let html = `<table class="probs-table"> | |
| <thead> | |
| <tr><th>Token</th><th>Index</th><th>${title}</th></tr> | |
| </thead> | |
| <tbody>`; | |
| probs.forEach((prob, i) => { | |
| let className = ''; | |
| if (i === selectedIndex) className = 'selected'; | |
| else if (originalProbs && probs[i] === 0) className = 'filtered'; | |
| html += `<tr class="${className}"> | |
| <td>${vocab[i]}</td> | |
| <td>${i}</td> | |
| <td>${prob.toFixed(4)}</td> | |
| </tr>`; | |
| }); | |
| html += '</tbody></table>'; | |
| return html; | |
| } | |
| function displayStrategy(title, result, description) { | |
| const hasOriginal = result.originalProbs !== undefined; | |
| let html = `<div class="strategy"> | |
| <h3>${title}</h3> | |
| <p><strong>Method:</strong> ${result.method}</p> | |
| <p>${description}</p>`; | |
| if (hasOriginal) { | |
| html += createProbabilityTable(result.originalProbs, -1, null, "Original Probs"); | |
| html += createProbabilityTable(result.probs, result.selectedIndex, result.originalProbs, "Filtered Probs"); | |
| } else { | |
| html += createProbabilityTable(result.probs, result.selectedIndex); | |
| } | |
| html += `<div class="result"> | |
| <strong>🎯 Selected Token:</strong> "${result.selectedToken}" (index: ${result.selectedIndex}) | |
| </div> | |
| </div>`; | |
| return html; | |
| } | |
| function runAllStrategies() { | |
| const temperature = parseFloat(document.getElementById('temperature').value); | |
| const k = parseInt(document.getElementById('topk').value); | |
| const p = parseFloat(document.getElementById('topp').value); | |
| const greedy = greedyDecoding(currentLogits); | |
| const tempSampling = temperatureSampling(currentLogits, temperature); | |
| const topK = topKSampling(currentLogits, k); | |
| const topP = topPSampling(currentLogits, p); | |
| let html = ''; | |
| html += displayStrategy( | |
| "🎯 Greedy Decoding", | |
| greedy, | |
| "Always selects the token with the highest probability. Deterministic and safe, but can be repetitive." | |
| ); | |
| html += displayStrategy( | |
| "🌡️ Temperature Sampling", | |
| tempSampling, | |
| "Applies temperature scaling to logits before sampling. Lower temperature = more focused, higher temperature = more random." | |
| ); | |
| html += displayStrategy( | |
| "🔝 Top-k Sampling", | |
| topK, | |
| "Only considers the k most probable tokens, zeros out the rest, then samples from the filtered distribution." | |
| ); | |
| html += displayStrategy( | |
| "🎯 Top-p (Nucleus) Sampling", | |
| topP, | |
| "Dynamically selects the smallest set of tokens whose cumulative probability exceeds p, then samples from them." | |
| ); | |
| document.getElementById('strategies-container').innerHTML = html; | |
| } | |
| function generateNewLogits() { | |
| currentLogits = generateRandomLogits(); | |
| document.getElementById('logits-display').innerHTML = | |
| `<strong>Raw Logits:</strong> [${currentLogits.map(x => x.toFixed(2)).join(', ')}]`; | |
| runAllStrategies(); | |
| } | |
| // Initialize | |
| generateNewLogits(); | |
| // Add event listeners for real-time updates | |
| document.getElementById('temperature').addEventListener('input', runAllStrategies); | |
| document.getElementById('topk').addEventListener('input', runAllStrategies); | |
| document.getElementById('topp').addEventListener('input', runAllStrategies); | |
| </script> | |
| </body> | |
| </html> |