Spaces:
Running
Running
Download app.js from alphabell/Model-Observatory: direct link, hf CLI and curl.
- Browser
- Download file 30.3 kB
-
https://huggingface.co/spaces/alphabell/Model-Observatory/resolve/refs%2Fpr%2F2/app.js
- Command line
-
hf download hf://spaces/alphabell/Model-Observatory@refs/pr/2/app.js
-
curl -L -o app.js https://huggingface.co/spaces/alphabell/Model-Observatory/resolve/refs%2Fpr%2F2/app.js
30.3 kB
| ; | |
| const $=id=>document.getElementById(id); | |
| const S={models:[],model:null,config:null,frames:[],frame:-1,layer:12,head:0,expert:null,live:true,running:false,requesting:false,switching:false,partial:[],activeLayer:-1,id:null,start:null,view:'structure',output:'',decoder:new TextDecoder(),timer:null,speed:500,slowOnRun:false,stream:null,trace:null,geometry:null,loadingTrace:false,detail:null}; | |
| const snapshots=new Map(); | |
| const pad=n=>String(n).padStart(2,'0'); | |
| const fmt=n=>Number.isFinite(n)?n.toFixed(3):'unmeasured'; | |
| const pct=n=>(100*n).toFixed(1)+'%'; | |
| const layerCount=()=>S.config.num_hidden_layers; | |
| const isLinear=(l=S.layer)=>S.config.layer_types[l]==='linear_attention'; | |
| const isMoe=(l=S.layer)=>Boolean(S.config.num_experts)&&!(S.config.mlp_only_layers||[]).includes(l)&&l>=(S.config.first_k_dense_replace||0); | |
| const headCount=(l=S.layer)=>isLinear(l)?S.config.linear_num_value_heads:S.config.num_attention_heads; | |
| const headDimension=(l=S.layer)=>isLinear(l)?S.config.linear_value_head_dim:S.config.head_dim; | |
| const keyHeadCount=(l=S.layer)=>isLinear(l)?S.config.linear_num_key_heads:S.config.num_key_value_heads; | |
| const keyHead=(h=S.head,l=S.layer)=>isLinear(l)?h%keyHeadCount(l):Math.floor(h/(headCount(l)/keyHeadCount(l))); | |
| function attentionLabel(l=S.layer){if(isLinear(l))return 'Recurrent linear attention';if(S.config.layer_types[l]==='sliding_attention')return 'Sliding attention · '+S.config.sliding_window;return (S.config.no_rope_layer_indices||[]).includes(l)?'Full attention · no RoPE':'Full attention · partial RoPE';} | |
| let toastTimer,drawQueued=false; | |
| function toast(message){$('toast').textContent=message;$('toast').hidden=false;clearTimeout(toastTimer);toastTimer=setTimeout(()=>$('toast').hidden=true,5000);} | |
| function current(){return S.live&&S.running&&S.partial.length?S.partial:S.frames[S.frame]?.layers||[];} | |
| function colour(value,max){const t=Math.max(0,Math.min(1,value/(max||1)));const a=[236,242,224],b=[26,113,83];return `rgb(${a.map((v,i)=>Math.round(v+(b[i]-v)*Math.pow(t,.7))).join(',')})`;} | |
| function scaleFor(layers){const v=layers.flatMap(l=>l?.heads||[]).filter(Number.isFinite).sort((a,b)=>a-b);return v[Math.floor(v.length*.95)]||1;} | |
| function update(){if(!S.config)return;requestDraw();renderInspector();renderPlayback();if(typeof renderDetail==='function')renderDetail();$('modelSelect').disabled=S.running||S.requesting||S.loadingTrace||S.switching;$('modelSelect').title=S.running?'Stop generation to switch models.':'Choose a model to inspect.';} | |
| function requestDraw(){if(drawQueued)return;drawQueued=true;requestAnimationFrame(()=>{drawQueued=false;if(S.config)draw();});} | |
| function draw(){ | |
| const canvas=$('modelCanvas'),box=canvas.parentElement.getBoundingClientRect(),w=box.width,h=box.height,dpr=window.devicePixelRatio||1; | |
| if(canvas.width!==Math.round(w*dpr)||canvas.height!==Math.round(h*dpr)){canvas.width=w*dpr;canvas.height=h*dpr;} | |
| const c=canvas.getContext('2d');c.setTransform(dpr,0,0,dpr,0,0);c.clearRect(0,0,w,h); | |
| const layers=current(),max=scaleFor(layers),top=71,bottom=h-38,rh=(bottom-top)/layerCount();c.textBaseline='middle';c.font='9px "IBM Plex Mono",monospace'; | |
| if(S.view==='history'){ | |
| const left=43,right=w-18,cw=(right-left)/Math.max(1,S.frames.length),hm=scaleFor(S.frames.flatMap(f=>f.layers||[])); | |
| c.fillStyle='#6e8361';c.textAlign='center';c.fillText('HEAD OUTPUT MAGNITUDE OVER TOKENS',w/2,26); | |
| if(!S.frames.length){c.fillStyle='#a3ae97';c.fillText('Open a measured trace to inspect its token history.',w/2,h/2);} | |
| for(let l=0;l<layerCount();l++){const y=top+l*rh;c.fillStyle='#91a088';c.textAlign='right';c.font='8px "IBM Plex Mono",monospace';c.fillText(pad(l),left-9,y+rh/2);for(let t=0;t<S.frames.length;t++){const vals=S.frames[t].layers[l]?.heads,avg=vals?.reduce((a,b)=>a+b,0)/headCount(l);c.fillStyle=Number.isFinite(avg)?colour(avg,hm):'#eff2e8';c.fillRect(left+t*cw,y+1,Math.max(1,cw-1),rh-2);}} | |
| if(S.frame>=0){c.strokeStyle='#31583a';c.lineWidth=1.3;c.strokeRect(left+S.frame*cw,top,Math.max(1,cw),rh*layerCount());} | |
| c.textAlign='left';c.fillStyle='#93a087';c.fillText('Layer ↓',left,top-14);c.textAlign='right';c.fillText('Generated token →',right,top-14);S.geometry={history:true,left,right,top,rh,cw,w,h};return; | |
| } | |
| const margin=w<410?7:17,left=margin+32,right=w-margin,usable=right-left-54,headW=usable*.43,expW=usable*.57,hx=left+12,ex=hx+headW+14,sx=right-9; | |
| c.fillStyle='#eff3e9';c.strokeStyle='#e1e8da';c.lineWidth=1;roundRect(c,w/2-79,11,158,25,5);c.fill();c.stroke();c.fillStyle='#6d815e';c.textAlign='center';c.font='8px "IBM Plex Mono",monospace';c.fillText('TOKEN → EMBEDDING · '+S.config.hidden_size,w/2,24); | |
| c.strokeStyle='#cad6bf';c.beginPath();c.moveTo(w/2,37);c.lineTo(w/2,44);c.stroke(); | |
| c.textAlign='left';c.fillStyle='#8d9c81';c.fillText('LAYER',margin,56);c.fillText(S.model.id==='qwen'?'48 RECURRENT / 24 FULL':headCount()+' ATTENTION HEADS',hx,56);c.fillText(S.config.num_experts?S.config.num_experts+' ROUTED EXPERTS':'DENSE FEED-FORWARD',ex,56);if(S.config.num_experts){c.textAlign='center';c.fillText('S',sx,56);} | |
| for(let l=0;l<layerCount();l++){ | |
| const y=top+l*rh,cy=y+rh/2,data=layers[l],selected=l===S.layer,full=S.config.layer_types[l]==='full_attention',count=headCount(l); | |
| if(selected){c.fillStyle='#edf3e5';roundRect(c,margin-3,y,w-2*margin+6,rh,2);c.fill();} | |
| if(S.running&&S.live&&S.activeLayer===l){c.fillStyle='#cee6af';roundRect(c,margin-3,y,w-2*margin+6,rh,2);c.fill();} | |
| c.fillStyle=full?'#7095a2':isLinear(l)?'#8fa99d':'#bbcbb0';c.fillRect(left-1,y+rh*.2,2,rh*.6);c.fillStyle=selected?'#3e643c':'#98a58c';c.textAlign='left';c.font='8px "IBM Plex Mono",monospace';c.fillText(pad(l),margin,cy); | |
| for(let head=0;head<count;head++){const hw=headW/count;c.fillStyle=data?.heads?colour(data.heads[head],max):'#e5ebdf';roundRect(c,hx+head*hw,y+rh*.22,Math.max(1,hw-1),rh*.56,.7);c.fill();if(selected&&head===S.head){c.strokeStyle='#214d36';c.lineWidth=.9;c.strokeRect(hx+head*hw-.5,y+rh*.17,hw-.3,rh*.66);}} | |
| c.strokeStyle='#d7e2cc';c.beginPath();c.moveTo(hx+headW+2,cy);c.lineTo(ex-3,cy);c.stroke(); | |
| if(!isMoe(l)){c.fillStyle=Number.isFinite(data?.ffn)?colour(data.ffn,max):data?'#c4dab5':'#e7ecdf';roundRect(c,ex,y+rh*.18,expW,rh*.64,1);c.fill();c.fillStyle=Number.isFinite(data?.ffn)&&data.ffn/max>.6?'#f4f9eb':'#8a9b7d';c.font='7px "IBM Plex Mono",monospace';c.fillText('DENSE FFN · '+S.config.intermediate_size,ex+5,cy);} | |
| else{const ew=expW/64,eh=rh*.8/4,ids=data?.experts||[];for(let expert=0;expert<S.config.num_experts;expert++){const rank=ids.indexOf(expert);c.fillStyle=rank>=0?colour(data.weights?.[rank]||.17,.27):'#e7ecdf';c.fillRect(ex+(expert%64)*ew,y+rh*.1+Math.floor(expert/64)*eh,Math.max(1,ew-.7),Math.max(.8,eh-.5));}c.fillStyle=data?.shared!==undefined?colour(data.shared,max):'#e6ecdd';roundRect(c,sx-3,y+rh*.22,6,rh*.56,1);c.fill();} | |
| } | |
| c.fillStyle='#eef3e6';c.strokeStyle='#e0e9d4';roundRect(c,w/2-85,h-27,170,22,4);c.fill();c.stroke();c.fillStyle='#7c916a';c.textAlign='center';c.font='8px "IBM Plex Mono",monospace';c.fillText('RMSNORM → LM HEAD → NEXT TOKEN',w/2,h-16);S.geometry={history:false,margin,left,hx,ex,sx,headW,expW,top,rh,w,h}; | |
| } | |
| function roundRect(c,x,y,w,h,r){c.beginPath();c.roundRect(x,y,w,h,r);} | |
| function ensureInspectorControls(){ | |
| if($('headGrid').children.length!==headCount()){$('headGrid').replaceChildren();for(let i=0;i<headCount();i++){const b=document.createElement('button');b.className='head';b.textContent=pad(i);b.ariaLabel='Inspect '+(isLinear()?'linear value':'attention')+' head '+i;b.onclick=()=>openDetail('head',i);$('headGrid').append(b);}} | |
| if($('expertGrid').children.length!==(S.config.num_experts||0)){$('expertGrid').replaceChildren();for(let i=0;i<(S.config.num_experts||0);i++){const b=document.createElement('button');b.className='expert';b.ariaLabel='Expert '+i;b.onclick=()=>openDetail('expert',i);$('expertGrid').append(b);}} | |
| } | |
| function renderInspector(){ | |
| if(!S.config)return;ensureInspectorControls();S.head=Math.min(S.head,headCount()-1); | |
| const l=S.layer,data=current()[l],dense=!isMoe(),linear=isLinear(),max=scaleFor(current()); | |
| $('layerNumber').textContent=pad(l);$('layerType').textContent=linear?'Linear':S.config.layer_types[l]==='full_attention'?'Full attention':'Sliding · '+S.config.sliding_window;$('flowAttention').textContent=attentionLabel();$('flowMlp').textContent=dense?'Dense FFN · '+S.config.intermediate_size:'Router → '+S.config.num_experts_per_tok+' + shared';$('prevLayer').disabled=l===0;$('nextLayer').disabled=l===layerCount()-1; | |
| $('headGridTitle').textContent=linear?'Recurrent value heads':'Attention heads';$('headGridCount').textContent=linear?headCount()+' V · '+keyHeadCount()+' K':headCount()+' Q · '+keyHeadCount()+' KV'; | |
| for(let i=0;i<headCount();i++){const b=$('headGrid').children[i];b.classList.toggle('selected',i===S.head);b.style.background=data?.heads?colour(data.heads[i],max):'';b.style.color=data?.heads&&data.heads[i]/max>.6?'#f4f9eb':'#7d926e';b.title=`Head ${i} · ${linear?'key':'KV'} head ${keyHead(i)}${data?.heads?' · output RMS '+fmt(data.heads[i]):''}`;} | |
| $('headLabel').textContent=`${linear?'Value head':'Head'} ${pad(S.head)} · ${linear?'K':'KV'} ${keyHead()}`;$('headValue').textContent=data?.heads?fmt(data.heads[S.head])+' RMS':'Awaiting trace'; | |
| $('expertTitle').textContent=dense?'Dense feed-forward':'Expert routing';$('expertCount').textContent=dense?S.config.intermediate_size+' width':(data?.experts?.length||S.config.num_experts_per_tok)+' of '+S.config.num_experts;$('expertGrid').hidden=dense;$('sharedExpert').hidden=dense; | |
| for(let i=0;i<(S.config.num_experts||0);i++){const b=$('expertGrid').children[i],index=data?.experts?.indexOf(i)??-1;b.classList.toggle('active',index>=0);b.classList.toggle('focused',S.expert===i);b.title=`Expert ${i}${index>=0?' · routing weight '+pct(data.weights[index]):' · not selected'}`;} | |
| $('expertList').replaceChildren(); | |
| if(dense){const b=document.createElement('button');b.className='dense-inspect';b.textContent=Number.isFinite(data?.ffn)?'Output '+fmt(data.ffn)+' RMS ↗':'Inspect dense feed-forward ↗';b.onclick=()=>openDetail('ffn');$('expertList').append(b);} | |
| else if(data?.experts){data.experts.forEach((id,i)=>{const b=document.createElement('button');b.className='expert-chip';b.title='Open expert '+id+' fullscreen';b.onclick=()=>openDetail('expert',id);const label=document.createElement('b');label.textContent='E'+String(id).padStart(3,'0');b.append(label,document.createTextNode(pct(data.weights[i])));$('expertList').append(b);});} | |
| else{$('expertList').innerHTML='<span class="muted">Run a prompt to see selected experts.</span>';} | |
| $('sharedValue').textContent=data?.shared!==undefined?fmt(data.shared)+' RMS':'Always active';$('sharedExpert').querySelector('i').style.background=data?.shared!==undefined?'#79ad56':'';renderAttention(data); | |
| } | |
| function recurrentReading(data,dest){ | |
| for(const [label,value]of [['Write gate',data?.write_gate?.[S.head]],['Memory retention',data?.retention?.[S.head]],['State RMS',data?.state_rms?.[S.head]]]){const row=document.createElement('div');row.className='recurrent-reading';const name=document.createElement('span');name.textContent=label;const v=document.createElement('strong');v.textContent=Number.isFinite(value)?label==='State RMS'?fmt(value):pct(value):'Awaiting trace';row.append(name,v);dest.append(row);} | |
| const note=document.createElement('p');note.className='recurrent-note';note.textContent='This head updates a recurrent memory instead of a token-position attention map.';dest.append(note); | |
| } | |
| function renderAttention(data){ | |
| const dest=$('attentionList');dest.replaceChildren();$('attentionTitle').textContent=isLinear()?'Recurrent memory':'Where this head attends';$('attentionCount').textContent=isLinear()?'Gated DeltaNet':'top 8 positions'; | |
| if(isLinear()){recurrentReading(data,dest);return;} | |
| const a=data?.attention?.[S.head];if(!a){const s=document.createElement('span');s.className='muted';s.textContent='Select a token to inspect its attention.';dest.append(s);return;} | |
| const tokens=[...(S.start?.tokens||[]),...S.frames.map(f=>f.text)]; | |
| for(const [pos,weight]of a.top){const row=document.createElement('div');row.className='attention-row';const p=document.createElement('span');p.className='pos';p.textContent=String(pos);const word=document.createElement('span');word.className='attention-word';word.style.setProperty('--weight',pct(weight));word.textContent=(tokens[pos]??'#'+pos).replace(/\n/g,'↵');word.title=tokens[pos]||'';const v=document.createElement('span');v.className='weight';v.textContent=pct(weight);row.append(p,word,v);dest.append(row);} | |
| const note=document.createElement('div');note.className='sink-note';note.textContent=(S.model.learned_sink?'Learned sink '+pct(a.sink)+' · ':'')+'Token entropy '+fmt(a.entropy)+' nats';dest.append(note); | |
| } | |
| function renderPlayback(){ | |
| const n=S.frames.length;$('frameLabel').textContent=`TOKEN ${String(Math.max(0,S.frame+1)).padStart(3,'0')} / ${String(n).padStart(3,'0')}`;$('scrubber').disabled=!n;$('scrubber').max=Math.max(0,n-1);$('scrubber').value=Math.max(0,S.frame);$('stepBack').disabled=S.frame<=0;$('stepForward').disabled=S.frame>=n-1;$('playButton').disabled=!n;$('exportButton').disabled=!n||S.running; | |
| $('liveButton').classList.toggle('live-selected',S.live);$('playButton').textContent=S.timer?'Ⅱ':'▶';$('playButton').ariaLabel=S.timer?'Pause trace':'Play trace'; | |
| $('playSpeed').value=String(S.speed); | |
| const strip=$('tokenStrip');if(n&&strip.children[0]?.className==='muted')strip.replaceChildren(); | |
| for(let i=strip.children.length;i<n;i++){const b=document.createElement('button');b.className='token';b.dataset.index=i;b.textContent=S.frames[i].text.replace(/\n/g,'↵')||'∅';b.title=`Output token ${i+1} · id ${S.frames[i].token_id} · ${fmt(S.frames[i].duration)} seconds`;b.onclick=()=>selectFrame(i);strip.append(b);} | |
| for(const child of strip.children)child.classList.toggle('selected',Number(child.dataset.index)===S.frame); | |
| $('tokenCount').textContent=n+' tokens'; | |
| if(S.frames[S.frame]){const f=S.frames[S.frame];$('captureLabel').textContent=`Measured frame ${S.frame+1} · input position ${f.input_position}`;} | |
| } | |
| function pausePlayback(){clearTimeout(S.timer);S.timer=null;} | |
| function selectFrame(i,follow=false,playing=false){if(!playing)pausePlayback();S.live=follow;S.frame=Math.min(S.frames.length-1,Math.max(0,i));S.partial=[];S.activeLayer=-1;update();} | |
| function playbackTick(){ | |
| if(S.frame<S.frames.length-1)selectFrame(S.frame+1,false,true); | |
| else if(!S.running){pausePlayback();update();return;} | |
| S.timer=setTimeout(playbackTick,S.speed); | |
| } | |
| function startPlayback(rewind=true){pausePlayback();S.live=false;S.partial=[];S.activeLayer=-1;if(rewind&&S.frame>=S.frames.length-1&&!S.running)S.frame=0;S.timer=setTimeout(playbackTick,S.speed);update();} | |
| function togglePlayback(){if(S.timer){pausePlayback();update();}else if(S.frames.length)startPlayback();} | |
| function changeSpeed(value){const wasPlaying=Boolean(S.timer),wasLive=S.live;S.speed=Number(value);S.slowOnRun=true;if(wasPlaying||(wasLive&&(S.frames.length||S.running)))startPlayback(false);else{S.live=false;update();}} | |
| function selectLayer(l){S.layer=Math.max(0,Math.min(layerCount()-1,l));if(S.detail!=='expert')S.expert=null;if(!isMoe()&&(S.detail==='expert'||S.detail==='shared'))S.detail='ffn';if(isMoe()&&S.detail==='ffn')S.detail='block';S.head=Math.min(S.head,headCount()-1);update();} | |
| function reset(){pausePlayback();S.frames=[];S.frame=-1;S.partial=[];S.output='';S.decoder=new TextDecoder();S.start=null;S.trace=null;S.activeLayer=-1;$('terminal').textContent='';$('tokenStrip').innerHTML='<span class="muted">Waiting for the first generated token.</span>';$('timing').textContent='Processing prompt';update();} | |
| function renderTerminal(){const terminal=$('terminal'),nearBottom=terminal.scrollHeight-terminal.scrollTop-terminal.clientHeight<60;terminal.textContent=S.output;if(S.running){const cursor=document.createElement('span');cursor.className='cursor';cursor.textContent='▌';terminal.append(cursor);}if(nearBottom)terminal.scrollTop=terminal.scrollHeight;} | |
| function renderIdentity(){ | |
| $('modelSelect').value=S.model.id;$('modelEyebrow').textContent=S.model.title.toUpperCase()+' · '+S.model.family.toUpperCase();$('quantization').textContent=S.model.quantization;$('promptLabel').textContent='Prompt '+S.model.short_name; | |
| document.title=S.model.short_name+' | Model Observatory';$('modelCanvas').ariaLabel=S.model.title+' architecture: '+layerCount()+' layers. Click a block, head or feed-forward branch to inspect it.'; | |
| $('modelStats').replaceChildren();for(const [value,secondary,label]of S.model.stats){const item=document.createElement('div'),strong=document.createElement('strong'),caption=document.createElement('span');strong.textContent=value;if(secondary){const small=document.createElement('small');small.textContent=' / '+secondary;strong.append(small);}caption.textContent=label;item.append(strong,caption);$('modelStats').append(item);} | |
| $('legendSecondary').textContent=S.config.layer_types.includes('linear_attention')?'Linear attention':'Sliding window';$('legendSecondarySwatch').className='swatch '+(S.config.layer_types.includes('linear_attention')?'linear':'sliding');$('legendActivation').textContent=S.config.num_experts?'Selected expert':'Dense FFN output'; | |
| $('aboutContent').replaceChildren();const paragraphs=[ | |
| S.model.title+' has '+layerCount()+' decoder blocks, hidden width '+S.config.hidden_size+' and a '+S.model.quantization+' tracing checkpoint. Head brightness is measured output RMS before the output projection. The colour scale uses the 95th percentile of the current frame; compare exact values across frames.', | |
| S.config.num_experts?'The router chooses '+S.config.num_experts_per_tok+' of '+S.config.num_experts+' experts in each MoE block, plus one shared expert. Blocks '+S.config.mlp_only_layers.join(' and ')+' use dense feed-forward networks. Every attention head executes.':S.config.layer_types.filter(t=>t==='linear_attention').length+' blocks use Gated DeltaNet with '+S.config.linear_num_value_heads+' value heads and '+S.config.linear_num_key_heads+' key heads. They update recurrent memory through measured write and retention gates. The other '+S.config.layer_types.filter(t=>t==='full_attention').length+' blocks use full attention with '+S.config.num_attention_heads+' query heads and '+S.config.num_key_value_heads+' KV heads. All blocks use dense feed-forward width '+S.config.intermediate_size+'.', | |
| 'Click any block or head for fullscreen inspection. Full-attention heads expose their strongest token positions. Recurrent heads expose write gates, memory retention and state RMS. A frame records the forward pass that predicts the selected output token.', | |
| 'These are recorded Q8_0 tensor captures, replayed locally in your browser. Step, scrub or pause to inspect a token. The speed changes playback only. Jump to end selects the final captured token.', | |
| 'The public Space replays saved captures; it does not run new prompts. Import a compatible trace JSON to inspect your own capture. Imported files stay in this tab and are never uploaded. Selecting another model preserves your current trace and selected token.' | |
| ];for(const text of paragraphs){const p=document.createElement('p');p.textContent=text;$('aboutContent').append(p);}$('aboutSource').href=S.model.source_url; | |
| } | |
| function cacheModel(){if(!S.model)return;snapshots.set(S.model.id,{frames:S.frames,frame:S.frame,id:S.id,start:S.start,trace:S.trace,output:S.output,prompt:$('prompt').value,settings:null});} | |
| function applyModel(model,restore=true){ | |
| if(S.model&&S.model.id!==model.id)cacheModel();if($('detailDialog').open)$('detailDialog').close();S.detail=null;if(typeof detailLayout!=='undefined')detailLayout=''; | |
| S.model=model;S.config=model.architecture;S.layer=model.id==='flint'?12:0;S.head=0;S.expert=null;S.id=null;S.live=true;reset();renderIdentity(); | |
| const saved=restore?snapshots.get(model.id):null;if(saved){Object.assign(S,{frames:saved.frames,frame:saved.frame,id:saved.id,start:saved.start,trace:saved.trace,output:saved.output,live:false});$('prompt').value=saved.prompt;renderTerminal();$('timing').textContent=S.frames.length+' tokens · recorded trace';} | |
| else{$('terminal').textContent=model.short_name.toLowerCase()+' > open a measured trace';$('captureLabel').textContent='Structure ready · loading measured trace';$('timing').textContent='Recorded Q8_0 capture';} | |
| const url=new URL(location.href);url.searchParams.set('model',model.id);history.replaceState({},'',url);update(); | |
| } | |
| async function switchModel(id){ | |
| if(id===S.model.id||S.loadingTrace||S.switching)return; | |
| const model=S.models.find(m=>m.id===id);if(!model)return; | |
| S.switching=true;applyModel(model);update(); | |
| try{await loadHistory();if(!S.frames.length)await openExample(id);else renderCapture(S.trace);}catch(e){captureError(e);}finally{S.switching=false;update();} | |
| } | |
| async function loadHistory(){ | |
| $('history').replaceChildren(); | |
| for(const row of examples.filter(r=>r.model===S.model.id)){ | |
| const b=document.createElement('button');b.className='history-row';b.textContent=row.tokens+' tokens · Sky explanation';b.title=row.prompt; | |
| b.onclick=()=>openExample(row.model).catch(captureError);$('history').append(b); | |
| } | |
| } | |
| function loadTrace(d){ | |
| const model=validateObservatoryTrace(d,S.models);if(S.model.id!==model.id)applyModel(model,false);S.stream?.close();reset();S.trace=d;S.id=d.id;S.start=d.start;S.frames=d.frames;S.frame=Math.max(-1,S.frames.length-1);S.live=false;S.output=S.frames.map(f=>f.token_bytes?S.decoder.decode(new Uint8Array(f.token_bytes),{stream:true}):f.text).join('')+S.decoder.decode();$('prompt').value=d.prompt||''; | |
| $('runNote').textContent='Recorded capture. Replay or select a token to inspect it.';renderCapture(d);$('timing').textContent=`${S.frames.length} tokens · recorded trace`;renderTerminal();update();loadHistory();toast(S.model.short_name+' measured trace loaded.'); | |
| } | |
| function download(){if(!S.trace)return;const a=document.createElement('a');a.download=S.model.id+'-trace.json';a.href=URL.createObjectURL(new Blob([JSON.stringify(S.trace)],{type:'application/json'}));a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);} | |
| function mapPoint(ev){ | |
| const b=$('modelCanvas').getBoundingClientRect(),x=ev.clientX-b.left,y=ev.clientY-b.top,g=S.geometry;if(!g)return null;const layer=Math.floor((y-g.top)/g.rh);if(layer<0||layer>=layerCount())return null; | |
| if(g.history){const frame=Math.floor((x-g.left)/g.cw);return frame>=0&&frame<S.frames.length?{layer,frame,x,y}:null;} | |
| const head=x>=g.hx&&x<g.hx+g.headW?Math.floor((x-g.hx)/g.headW*headCount(layer)):null,expert=x>=g.ex&&x<g.ex+g.expW&&isMoe(layer)?Math.floor((x-g.ex)/g.expW*64)+64*Math.max(0,Math.min(3,Math.floor(((y-g.top-layer*g.rh)/g.rh-.1)/.8*4))):null; | |
| return {layer,head,expert,ffn:!isMoe(layer)&&x>=g.ex&&x<g.ex+g.expW,x,y}; | |
| } | |
| function initControls(){ | |
| $('shareButton').onclick=async()=>{const url=new URL(location.href);url.searchParams.set('layer',S.layer);url.searchParams.set('token',S.frame+1);try{await navigator.clipboard.writeText(url.href);toast('Example view link copied. Imported traces are not included.');}catch{toast('Copy the address from your browser to share this model.');}}; | |
| $('modelSelect').onchange=()=>switchModel($('modelSelect').value);$('openBlock').onclick=()=>openDetail('block');$('flowAttention').onclick=()=>openDetail('head');$('flowMlp').onclick=()=>openDetail(isMoe()?'expert':'ffn');$('sharedExpert').onclick=()=>openDetail('shared'); | |
| $('runButton').onclick=()=>{if(S.frames.length){selectFrame(0);startPlayback(false);}else openExample(S.model.id).catch(captureError);}; | |
| $('prevLayer').onclick=()=>selectLayer(S.layer-1);$('nextLayer').onclick=()=>selectLayer(S.layer+1);$('scrubber').oninput=()=>selectFrame(Number($('scrubber').value));$('stepBack').onclick=()=>selectFrame(S.frame-1);$('stepForward').onclick=()=>selectFrame(S.frame+1);$('liveButton').onclick=()=>selectFrame(S.frames.length-1);$('playButton').onclick=togglePlayback;$('playSpeed').onchange=()=>changeSpeed($('playSpeed').value); | |
| $('structureButton').onclick=()=>{S.view='structure';$('structureButton').classList.add('selected');$('historyButton').classList.remove('selected');requestDraw();};$('historyButton').onclick=()=>{S.view='history';$('historyButton').classList.add('selected');$('structureButton').classList.remove('selected');requestDraw();}; | |
| $('modelCanvas').onkeydown=e=>{if(e.key==='ArrowDown'||e.key==='ArrowUp'){e.preventDefault();selectLayer(S.layer+(e.key==='ArrowDown'?1:-1));}if(e.key==='Enter'){e.preventDefault();openDetail('block');}};$('modelCanvas').onclick=e=>{const p=mapPoint(e);if(!p)return;S.layer=p.layer;S.head=Math.min(S.head,headCount()-1);if(p.frame!==undefined){selectFrame(p.frame);openDetail('block');}else if(p.head!==null&&p.head!==undefined)openDetail('head',p.head);else if(p.expert!==null&&p.expert!==undefined)openDetail('expert',p.expert);else if(p.ffn)openDetail('ffn');else if(isMoe()&&Math.abs(p.x-S.geometry.sx)<9)openDetail('shared');else openDetail('block');}; | |
| $('modelCanvas').onmousemove=e=>{const p=mapPoint(e),tip=$('mapTooltip');if(!p){tip.hidden=true;return;}const d=(p.frame!==undefined?S.frames[p.frame].layers:current())[p.layer];let text=`Layer ${pad(p.layer)} · ${attentionLabel(p.layer)}`;if(p.head!==null&&p.head!==undefined)text+=`\n${isLinear(p.layer)?'Value head':'Head'} ${pad(p.head)}${d?.heads?' · '+fmt(d.heads[p.head])+' output RMS':''}`;if(p.expert!==null&&p.expert!==undefined){const i=d?.experts?.indexOf(p.expert)??-1;text+=`\nExpert ${p.expert}${d?i>=0?' · selected · '+pct(d.weights[i]):' · not selected':' · awaiting trace'}`;}if(p.ffn)text+='\nDense FFN · '+S.config.intermediate_size+(Number.isFinite(d?.ffn)?' · '+fmt(d.ffn)+' RMS':'');tip.textContent=text;tip.hidden=false;tip.style.left=Math.max(0,Math.min(p.x+12,S.geometry.w-230))+'px';tip.style.top=Math.min(p.y+12,S.geometry.h-70)+'px';};$('modelCanvas').onmouseleave=()=>$('mapTooltip').hidden=true; | |
| $('exportButton').onclick=download;$('importButton').onclick=()=>$('importFile').click();$('importFile').onchange=async e=>{let loading=false;try{if(S.running||S.requesting||S.loadingTrace)throw new Error('Stop the current generation before importing a trace.');const f=e.target.files[0];if(!f)return;if(f.size>160000000)throw new Error('Trace file exceeds 160 MB.');loading=true;S.loadingTrace=true;$('runButton').disabled=true;update();loadTrace(JSON.parse(await f.text()));}catch(e){toast(e.message);}finally{if(loading){S.loadingTrace=false;update();if(S.trace)renderCapture(S.trace);else $('runButton').disabled=false;}$('importFile').value='';}}; | |
| $('copyButton').onclick=async()=>{try{await navigator.clipboard.writeText(S.output);toast('Output copied.');}catch{toast('Select the output text to copy it.');}};$('aboutButton').onclick=()=>$('aboutDialog').showModal();$('metricInfo').onclick=()=>$('aboutDialog').showModal();$('closeAbout').onclick=()=>$('aboutDialog').close(); | |
| new ResizeObserver(requestDraw).observe($('mapContainer')); | |
| } | |
| async function init(){ | |
| try{ | |
| [S.models,examples]=await Promise.all([readJSON('models.json'),readJSON('traces/index.json')]); | |
| $('modelSelect').replaceChildren();for(const m of S.models)$('modelSelect').add(new Option(m.title,m.id)); | |
| const query=new URL(location.href).searchParams,model=S.models.find(m=>m.id===query.get('model'))||S.models[0]; | |
| initControls();applyModel(model);await loadHistory();await openExample(model.id); | |
| const layer=Number(query.get('layer')),frame=Number(query.get('token')); | |
| if(query.has('layer')&&Number.isInteger(layer))selectLayer(layer); | |
| if(query.has('token')&&Number.isInteger(frame))selectFrame(frame-1); | |
| }catch(e){captureError(e);} | |
| } | |
| let examples=[]; | |
| const traceCache=new Map(); | |
| async function readJSON(file){const r=await fetch(file);if(!r.ok)throw new Error('Could not load '+file+'. Try reloading.');return r.json();} | |
| async function sha256(bytes){return Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',bytes)),b=>b.toString(16).padStart(2,'0')).join('');} | |
| function captureError(e){$('engineStatus').textContent='Trace unavailable';$('runNote').textContent=e.message;$('runButton').disabled=false;$('runButton').textContent='Retry trace';toast(e.message);} | |
| function renderCapture(d){ | |
| if(!d)return;const settings=d.settings||{}; | |
| $('captureSettings').textContent='Temperature '+(settings.temperature??'unmeasured')+' · seed '+(settings.seed??'unmeasured')+' · reasoning '+(settings.reasoning?'on':'off'); | |
| $('engineStatus').replaceChildren(document.createElement('i'),document.createTextNode('Measured Q8 replay'));$('engineStatus').classList.add('ready'); | |
| $('runButton').textContent='▶ Replay from start';$('runButton').disabled=false; | |
| $('traceOrigin').textContent=examples.some(e=>e.id===d.id)?'Example capture · '+S.frames.length+' tokens':'Imported capture · '+S.frames.length+' tokens'; | |
| } | |
| async function openExample(id){ | |
| if(S.loadingTrace)return;const row=examples.find(r=>r.model===id);if(!row)throw new Error('No example capture is available for this model.'); | |
| S.loadingTrace=true;$('runButton').disabled=true;$('runNote').textContent='Loading measured capture…';update(); | |
| try{ | |
| let d=traceCache.get(id); | |
| if(!d){ | |
| const response=await fetch(row.file);if(!response.ok)throw new Error('The example capture could not load. Try again.'); | |
| const compressed=await response.arrayBuffer();if(await sha256(compressed)!==row.gzip_sha256)throw new Error('Capture checksum failed. Reload to get the latest files.'); | |
| if(typeof DecompressionStream==='undefined')throw new Error('This browser needs gzip stream support. Open in a current Chrome, Firefox or Safari.'); | |
| const plain=await new Response(new Blob([compressed]).stream().pipeThrough(new DecompressionStream('gzip'))).arrayBuffer(); | |
| if(await sha256(plain)!==row.sha256)throw new Error('Decoded capture checksum failed. Reload to try again.'); | |
| d=JSON.parse(new TextDecoder().decode(plain));validateObservatoryTrace(d,S.models);traceCache.set(id,d); | |
| } | |
| loadTrace(d);selectFrame(0);$('runNote').textContent='Real tensor capture. Press Replay or select a token.'; | |
| }finally{S.loadingTrace=false;update();} | |
| } | |
| init(); | |