From 06d56c9fc6471215149ad8b4f4fe9abb344dac84 Mon Sep 17 00:00:00 2001 From: hash-panda <110599333+hash-panda@users.noreply.github.com> Date: Wed, 28 Oct 2026 14:45:36 +0800 Subject: [PATCH 1/2] Fix token-choice morph ownership; keep craft rework pending browser review --- apps/site/learn/token-choice/LESSON.md | 4 + apps/site/learn/token-choice/SCENE_SPEC.json | 146 ++++++++++++++---- apps/site/learn/token-choice/geometry.mjs | 24 +++ .../site/learn/token-choice/geometry.test.mjs | 39 +++++ apps/site/learn/token-choice/model.mjs | 2 +- apps/site/learn/token-choice/stage.mjs | 48 +++--- apps/site/learn/token-choice/style.css | 5 + docs/ai-learning/STATUS.md | 6 +- .../reviews/2026-10-28-token-choice-rework.md | 32 ++++ docs/ai-learning/roadmap.json | 9 +- package.json | 2 +- 11 files changed, 266 insertions(+), 51 deletions(-) create mode 100644 apps/site/learn/token-choice/geometry.mjs create mode 100644 apps/site/learn/token-choice/geometry.test.mjs create mode 100644 docs/ai-learning/reviews/2026-10-28-token-choice-rework.md diff --git a/apps/site/learn/token-choice/LESSON.md b/apps/site/learn/token-choice/LESSON.md index b03fcc3..c91767b 100644 --- a/apps/site/learn/token-choice/LESSON.md +++ b/apps/site/learn/token-choice/LESSON.md @@ -67,3 +67,7 @@ node apps/site/learn/token-choice/model.test.mjs 通过开发者教学适配评审,尚未进行真实学习者效果研究。加入完成后的“检验理解”:先预测固定分数和u不变、T从.8到2时的候选,再得到累计概率区间的因果反馈,最后回到同一组参数的图形验证。错误答案不是只显示叉号;说明mat上界.4551、floor上界.7311,以及u=.6219为何属于floor。 本轮实查:课程入口可进入该场景;桌面端错误/正确选择与回到图形后T=2、floor27.6%一致;390×844手机布局下学习题完整可读。`npm run check`覆盖既有机械模板约束、新场景的独立模型测试与课程清单检查。真实设备与屏幕阅读器仍未实查。 + +## Reopened visual review: draft repair — 2026-10-28 + +The 32s probability-label defect has a source-level repair using shared geometry and ordered identity lanes. Numerical ownership/non-overlap/CDF/continuous-focus/reverse-seek checks cover3,620 poses. Full site checks pass. See `docs/ai-learning/reviews/2026-10-28-token-choice-rework.md` for precise changes and remaining gates. Browser connection was unavailable; no actual screenshots,390px legibility,lifecycle or4× craft acceptance were performed for this candidate. It is not published or visually accepted. Earlier published evidence remains historical and does not validate this new code. diff --git a/apps/site/learn/token-choice/SCENE_SPEC.json b/apps/site/learn/token-choice/SCENE_SPEC.json index fb5cf3b..8047064 100644 --- a/apps/site/learn/token-choice/SCENE_SPEC.json +++ b/apps/site/learn/token-choice/SCENE_SPEC.json @@ -4,12 +4,36 @@ "audience": "希望逐步理解 AI 原理、没有概率论背景的读者", "context": "the cat sat on the …", "objects": [ - {"id":"scores","meaning":"四个教学候选的原始 logits,保留候选身份与颜色","units":"无量纲分数"}, - {"id":"temperature","meaning":"把每个原始分数除以同一温度 T","units":"无量纲"}, - {"id":"weights","meaning":"exp(z/T) 给出的正权重,尚未归一化","units":"无量纲权重"}, - {"id":"probability","meaning":"每个权重除以全部权重之和,概率带宽度正比于概率","units":"概率,合计 1 或 100%"}, - {"id":"sampling","meaning":"0 到 1 的均匀随机数 u 在累积概率带上的位置","units":"无量纲,0 ≤ u < 1"}, - {"id":"result","meaning":"u 所在区间对应的候选词卡","units":"候选索引"} + { + "id": "scores", + "meaning": "四个教学候选的原始 logits,保留候选身份与颜色", + "units": "无量纲分数" + }, + { + "id": "temperature", + "meaning": "把每个原始分数除以同一温度 T", + "units": "无量纲" + }, + { + "id": "weights", + "meaning": "exp(z/T) 给出的正权重,尚未归一化", + "units": "无量纲权重" + }, + { + "id": "probability", + "meaning": "每个权重除以全部权重之和,概率带宽度正比于概率", + "units": "概率,合计 1 或 100%" + }, + { + "id": "sampling", + "meaning": "0 到 1 的均匀随机数 u 在累积概率带上的位置", + "units": "无量纲,0 ≤ u < 1" + }, + { + "id": "result", + "meaning": "u 所在区间对应的候选词卡", + "units": "候选索引" + } ], "relationships": [ "tokens = [mat, floor, bed, sofa];logits = [3, 2, 1, 0]", @@ -21,26 +45,81 @@ "固定输入下调节温度不改变原始 logits;固定 seed 和 draw 不改变随机数 u" ], "parameters": [ - {"id":"temperature","min":0.4,"max":2,"default":0.8,"units":"无量纲"}, - {"id":"seed","default":22,"units":"整数伪随机种子"}, - {"id":"draw","default":0,"min":0,"units":"非负整数抽样序号"} + { + "id": "temperature", + "min": 0.4, + "max": 2, + "default": 0.8, + "units": "无量纲" + }, + { + "id": "seed", + "default": 22, + "units": "整数伪随机种子" + }, + { + "id": "draw", + "default": 0, + "min": 0, + "units": "非负整数抽样序号" + } + ], + "outputs": [ + "scaled", + "weights", + "totalWeight", + "p", + "cdf", + "entropy", + "u", + "selected" ], - "outputs": ["scaled","weights","totalWeight","p","cdf","entropy","u","selected"], "durationSeconds": 50, "chapters": [ - {"id":"scores","start":0,"end":8,"message":"分数不是概率"}, - {"id":"temperature","start":8,"end":18,"message":"除以温度,缩放分数差异"}, - {"id":"weights","start":18,"end":27,"message":"取指数,把分差变成权重之比"}, - {"id":"probability","start":27,"end":36,"message":"归一化得到总和为 1 的概率"}, - {"id":"sampling","start":36,"end":45,"message":"随机数在累积概率带上定位"}, - {"id":"result","start":45,"end":50,"message":"显示这一次抽到的候选"} + { + "id": "scores", + "start": 0, + "end": 8, + "message": "分数不是概率" + }, + { + "id": "temperature", + "start": 8, + "end": 18, + "message": "除以温度,缩放分数差异" + }, + { + "id": "weights", + "start": 18, + "end": 27, + "message": "取指数,把分差变成权重之比" + }, + { + "id": "probability", + "start": 27, + "end": 36, + "message": "归一化得到总和为 1 的概率" + }, + { + "id": "sampling", + "start": 36, + "end": 45, + "message": "随机数在累积概率带上定位" + }, + { + "id": "result", + "start": 45, + "end": 50, + "message": "显示这一次抽到的候选" + } ], "timeline": { - "sampler":"sample(time, {temperature, seed, draw})", - "selectionVisibleAtSeconds":43.2, - "numericState":"所有数值从同一组输入计算,几何变形插值不改变它们的数学定义", - "playback":"实际 elapsed time,支持暂停、继续、反向拖动、重播与结束恢复;隐藏标签页暂停", - "narration":"每次仅一条气泡跟随当前数学对象;颜色在所有阶段保持候选身份一致" + "sampler": "sample(time, {temperature, seed, draw})", + "selectionVisibleAtSeconds": 43.2, + "numericState": "所有数值从同一组输入计算,几何变形插值不改变它们的数学定义", + "playback": "实际 elapsed time,支持暂停、继续、反向拖动、重播与结束恢复;隐藏标签页暂停", + "narration": "每次仅一条气泡跟随当前数学对象;颜色在所有阶段保持候选身份一致", + "probabilityMorph": "chartBandGeometry drives front faces, identity-lane values, connectors and continuous focus. During representation change, widths/heights are transitional; final band width encodes probability." }, "invariants": [ "四个概率均为正且总和约为 1", @@ -49,7 +128,10 @@ "在这组不相等的 logits 上,提高 T 提高熵并降低最大概率", "seed、draw、temperature 和 time 相同时,状态完全可重现", "43.2 秒前 selected 为 null;之后与 inverse CDF 结果一致", - "对返回数组的修改不会污染后续 sample 或原始教学数据" + "对返回数组的修改不会污染后续 sample 或原始教学数据", + "Probability labels stay below all moving front faces and retain one ordered candidate identity lane", + "Probability connectors originate at their owning current front face; focus remains within that face", + "Final front-face band widths and cumulative positions equal p and cdf without extrusion" ], "simplifications": [ "四个词构成完整的教学词表;不是从真实模型词表截取的前四项,也不是线上模型输出", @@ -64,9 +146,18 @@ "高温不会保证每个低排名候选的概率都增大,也不意味着答案更正确" ], "sources": [ - {"url":"https://docs.pytorch.org/docs/2.14/generated/torch.nn.Softmax.html","supports":"指数归一化公式与输出概率和为 1"}, - {"url":"https://huggingface.co/docs/transformers/en/internal/generation_utils#transformers.TemperatureLogitsWarper","supports":"正温度对采样分布的调节;温度与随机采样的关系"}, - {"url":"https://github.com/wheresryan22/anatomy","supports":"已获用户认可的细线、等轴层次与克制配色工艺参考;本场景不复用原轮盘几何"} + { + "url": "https://docs.pytorch.org/docs/2.14/generated/torch.nn.Softmax.html", + "supports": "指数归一化公式与输出概率和为 1" + }, + { + "url": "https://huggingface.co/docs/transformers/en/internal/generation_utils#transformers.TemperatureLogitsWarper", + "supports": "正温度对采样分布的调节;温度与随机采样的关系" + }, + { + "url": "https://github.com/wheresryan22/anatomy", + "supports": "已获用户认可的细线、等轴层次与克制配色工艺参考;本场景不复用原轮盘几何" + } ], "acceptance": [ "独立 Python 黄金值与 JavaScript 数学结果一致", @@ -75,5 +166,8 @@ "播放、暂停、继续、拖动、参数改变、再次抽样、重播及完成后的配置恢复均可观察验证", "保留单一焦点;未讲到的计算与参数不会同时占据主视觉" ], - "untested": ["真实手机硬件性能与所有浏览器组合", "独立的学习效果实验"] + "untested": [ + "真实手机硬件性能与所有浏览器组合", + "独立的学习效果实验" + ] } diff --git a/apps/site/learn/token-choice/geometry.mjs b/apps/site/learn/token-choice/geometry.mjs new file mode 100644 index 0000000..6b63321 --- /dev/null +++ b/apps/site/learn/token-choice/geometry.mjs @@ -0,0 +1,24 @@ +// Front-face coordinates only. Extrusion is decorative and never changes a value. +const clamp = x => Math.max(0, Math.min(1, x)); +const ease = x => { x = clamp(x); return x*x*(3-2*x); }; +const mix = (a,b,t) => a+(b-a)*t; +export function chartBandGeometry(frame, mobile=false) { + const width=mobile?390:1000, height=mobile?430:420; + const base=mobile?280:285, plotH=mobile?204:225, barW=mobile?32:110; + const xs=mobile?[75,153,231,309]:[130,345,560,775]; + const bandX=mobile?25:110, bandW=mobile?340:780, bandY=170, bandH=mobile?60:72; + let morph=frame.phase>3?1:frame.phase===3?ease((frame.progress-.27)/.46):0; + if(frame.reducedMotion&&frame.phase===3)morph=frame.progress>=.5?1:0; + const candidates=frame.p.map((p,i)=>{ + const h=p*plotH, x=mix(xs[i],bandX+frame.cdf[i]*bandW,morph); + const y=mix(base-h,bandY,morph), w=mix(barW,p*bandW,morph), height=mix(h,bandH,morph); + // Wide, ordered identity lanes remain readable even for a 0.05% interval. + // The connector always starts on THIS candidate's current front face. + const labelX=mix(xs[i]+barW/2,bandX+bandW*(i+.5)/4,morph); + const labelY=mix(base+48,bandY+bandH+69,morph); + return {x,y,w,h:height,labelX,labelY,valueX:labelX,valueY:labelY+22, + leader:{x:x+w/2,y:y+height+3,endX:labelX,endY:labelY-21}, + focus:{x:x+w/2,y:y+height*.3}}; + }); + return {width,height,base,plotH,barW,xs,bandX,bandW,bandY,bandH,morph,candidates}; +} diff --git a/apps/site/learn/token-choice/geometry.test.mjs b/apps/site/learn/token-choice/geometry.test.mjs new file mode 100644 index 0000000..a5637b9 --- /dev/null +++ b/apps/site/learn/token-choice/geometry.test.mjs @@ -0,0 +1,39 @@ +import assert from 'node:assert/strict'; +import {sample} from './model.mjs'; +import {chartBandGeometry} from './geometry.mjs'; +const close=(a,b,t=1e-8)=>assert.ok(Math.abs(a-b){ + assert.ok(c.w>0&&c.h>0); + assert.ok(c.x>=0&&c.x+c.w<=g.width); + if(i<3)assert.ok(c.x+c.w<=g.candidates[i+1].x+1e-8,'front faces must not overlap'); + // Every number stays in a readable identity lane BELOW all candidate faces. + for(const other of g.candidates)assert.ok(c.valueY>other.y+other.h+20,'number inside another candidate'); + close(c.valueX,c.labelX); + close(c.leader.x,c.x+c.w/2);close(c.leader.y,c.y+c.h+3); + close(c.leader.endX,c.labelX); + assert.ok(c.focus.x>=c.x&&c.focus.x<=c.x+c.w&&c.focus.y>=c.y&&c.focus.y<=c.y+c.h); + }); + if(time===36){ + close(g.candidates.reduce((a,c)=>a+c.w,0),g.bandW); + g.candidates.forEach((c,i)=>{close(c.w/g.bandW,frame.p[i]);close((c.x-g.bandX)/g.bandW,frame.cdf[i]);}); + } + checked++; + } + // An arbitrary backward traversal reproduces the same complete pose exactly. + for(let tick=180;tick>=0;tick-=7)assert.deepEqual(chartBandGeometry({...sample(27+tick/20,{temperature}),reducedMotion},mobile),states[tick]); + if(!reducedMotion)for(let i=1;imid.candidates[0].y+mid.candidates[0].h); +assert.ok(floor.valueX>mid.candidates[0].valueX); +console.log(`Token choice geometry: ${checked} intermediate poses; ownership, non-overlap, CDF scale, continuous focus, reverse seek passed. Browser visual acceptance remains separate.`); diff --git a/apps/site/learn/token-choice/model.mjs b/apps/site/learn/token-choice/model.mjs index 1922a07..774a802 100644 --- a/apps/site/learn/token-choice/model.mjs +++ b/apps/site/learn/token-choice/model.mjs @@ -53,7 +53,7 @@ export function narration(frame){ {eyebrow:'看这里 · 候选分数',title:'先有分数,还没有概率。',body:'同一个输入,四个候选各有一个分数。数值越大,倾向越强;它们还不是百分比。',formula:'教学分数 z = [3, 2, 1, 0]'}, {eyebrow:'看这里 · 温度缩放',title:'除以温度,改变分数之间的差距。',body:`原始分数保持不变。T = ${t} 时,相邻候选的分差从 1 变为 ${number(1/temperature)}。`,formula:`3 ÷ ${t} = ${number(scaled[0])};2 ÷ ${t} = ${number(scaled[1])}`}, {eyebrow:'看这里 · 指数权重',title:'取指数,让分差变成权重之比。',body:'每个数经过指数运算,得到一个正的权重。高分候选获得更多权重,此时总和还不是 1。',formula:`exp(${number(scaled[0])}) = ${number(weights[0])};权重总和 = ${number(totalWeight)}`}, - {eyebrow:'看这里 · 概率分布',title:frame.progress<.73?'每个权重除以总和,得到概率。':'除以总和,所有机会合成 100%。',body:frame.progress<.73?'四个概率的总和为 1。现在把这组概率重新排成一条带,候选与颜色保持不变。':'每个权重都除以同一个总和。彩色区间的宽度,就表示这个候选被抽中的概率。',formula:`P(mat) = ${number(weights[0])} ÷ ${number(totalWeight)} = ${percent(p[0])}%`}, + {eyebrow:'看这里 · 概率分布',title:frame.progress<.73?'每个权重除以总和,得到概率。':'除以总和,所有机会合成 100%。',body:frame.progress<.73?'同色连线始终连着同一个候选;数值不变,高度正变成区间宽度。':'四段合为 100%;区间越宽,被均匀随机数命中的机会越大。',formula:`P(mat) = ${number(weights[0])} ÷ ${number(totalWeight)} = ${percent(p[0])}%`}, {eyebrow:'看这里 · 随机数游标',title:selected===null?'一个随机数,落入一个概率区间。':`游标落定,选中了 ${TOKENS[selected]}。`,body:'先生成 0 到 1 之间的均匀随机数。游标展示它的位置,落入哪个区间,就选哪个候选。',formula:`u = ${u.toFixed(4)};选择满足 Cᵢ ≤ u < Cᵢ₊₁ 的候选`}, {eyebrow:'看这里 · 这次的选择',title:`这次得到 ${TOKENS[selected]??'一个候选'}。`,body:`${selected===null?'':ZH[selected]+' · 概率 '+percent(p[selected])+'%。'}同一个输入再抽一次,可能选到别的候选。`,formula:'固定上下文的一次采样 · 本节没有继续生成后续 Token'} ][phase]; diff --git a/apps/site/learn/token-choice/stage.mjs b/apps/site/learn/token-choice/stage.mjs index e46d8a5..ae74c4a 100644 --- a/apps/site/learn/token-choice/stage.mjs +++ b/apps/site/learn/token-choice/stage.mjs @@ -1,3 +1,4 @@ +import {chartBandGeometry} from './geometry.mjs'; /** * A mathematical scene for Explain3D. Original vector geometry, inspired by * Anatomy's disciplined strokes and surface hierarchy. No wheel geometry reused. @@ -29,7 +30,7 @@ const css=` .guide{fill:none;stroke:#b2bfce;stroke-width:.6;stroke-dasharray:2 4} .grid{stroke:#dfe5ea;stroke-width:.5} .bright{stroke:#fff;stroke-width:1;fill:none} - .mobile .axis{font-size:13px}.mobile .number{font-size:18px}.mobile .note{font-size:13px}.mobile .small{font-size:12px}.mobile .translation{font-size:12px}.mobile .token{font-size:23px}.mobile .formula{font-size:16px} + .mobile .axis{font-size:16px}.mobile .number{font-size:18px}.mobile .note{font-size:16px}.mobile .small{font-size:16px}.mobile .translation{font-size:16px}.mobile .token{font-size:22px}.mobile .formula{font-size:16px} `; function node(tag,attrs={},parent){const n=document.createElementNS(NS,tag);for(const[k,v]of Object.entries(attrs))n.setAttribute(k,String(v));parent?.append(n);return n;} @@ -72,6 +73,8 @@ export function createStage(host){ text(label,token);text(translation,CHINESE[i]); return{g,ghost,side,front,top,shine,seam,foot,operation,operationLine,operationDot,number,original,labelGroup,dot,label,translation}; }); + const bandDock=node('g',{opacity:0},baseGroup.parentNode),dockEdge=node('path',{fill:'#eef1f3',stroke:'#bec9d3','stroke-width':.6},bandDock),dockLip=node('path',{fill:'none',stroke:'#fff','stroke-width':1},bandDock); + svg.insertBefore(bandDock,barGroup); const bandScale=node('g',{opacity:0},svg),bandTicks=[]; for(let i=0;i<=20;i++){const tick=node('line',{class:'fine'},bandScale);const label=i%5===0?node('text',{class:'axis','text-anchor':'middle'},bandScale):null;bandTicks.push({tick,label});} const bandBounds=node('g',{},bandScale),bounds=Array.from({length:3},()=>node('path',{fill:'none',stroke:'#b0bdca','stroke-width':.65},bandBounds)); @@ -83,17 +86,15 @@ export function createStage(host){ let lastFrame=null,disposed=false,anchors={},width=1000,height=560; function render(frame){ if(disposed)return;lastFrame=frame; - const mobile=host.getBoundingClientRect().width<600; width=mobile?560:1000;height=mobile?430:420; + const mobile=host.getBoundingClientRect().width<600; + const layout=chartBandGeometry(frame,mobile); ({width,height}=layout); attr(svg,{viewBox:`0 0 ${width} ${height}`,class:mobile?'mobile':'desktop'}); const phase=clamp(frame.phase,0,5),pr=clamp(frame.progress??0),P=frame.p,T=frame.temperature; const cdf=frame.cdf?.length===5?frame.cdf:[0,...P.map((_,i)=>P.slice(0,i+1).reduce((a,b)=>a+b,0))]; - const chosen=frame.selected,base=mobile?290:285,plotH=mobile?214:225,barW=mobile?62:110,dx=mobile?7:11,dy=mobile?5:8; - const xs=mobile?[91,202,313,424]:[130,345,560,775]; - const axisX=mobile?64:87,plotEnd=xs[3]+barW+dx; - const bandX=mobile?52:110,bandW=mobile?456:780,bandY=170,bandH=mobile?68:72; - let morph=phase>3?1:phase===3?ease((pr-.27)/.46):0; - if(frame.reducedMotion&&phase===3)morph=pr>=.5?1:0; - const isBand=morph>.99,chartOpacity=1-morph; + const chosen=frame.selected,dx=mobile?5:11,dy=mobile?4:8; + const {base,plotH,barW,xs,bandX,bandW,bandY,bandH,morph}=layout; + const axisX=mobile?57:87,plotEnd=xs[3]+barW+dx; + const chartOpacity=1-morph; let values=frame.logits,max=4,axisTitle='原始分数 z'; if(phase===1){values=frame.scaled;max=8;axisTitle='缩放分数 z / T';} if(phase===2){values=frame.weights;max=Math.max(...values);axisTitle='指数权重 exp(z / T)';} @@ -111,9 +112,10 @@ export function createStage(host){ bars.forEach((b,i)=>{ const color=frame.color===false?['#8e9bad','#9eabba','#aeb9c5','#bdc7d0'][i]:COLORS[i]; gradients[i].forEach(stop=>stop.setAttribute('stop-color',color));attr(b.side,{fill:color});attr(b.front,{stroke:color});attr(b.dot,{fill:color});attr(b.seam,{stroke:color}); - const h=Math.max(0,values[i]/max*plotH),targetX=bandX+cdf[i]*bandW,targetW=P[i]*bandW; - const x=mix(xs[i],targetX,morph),y=mix(base-h,bandY,morph),w=mix(barW,targetW,morph),hh=mix(h,bandH,morph); - const depthX=mix(dx,mobile?5:8,morph),depthY=mix(dy,mobile?4:6,morph); + const h=Math.max(0,values[i]/max*plotH); + const owned=layout.candidates[i]; + const x=phase>=3?owned.x:xs[i],y=phase>=3?owned.y:base-h,w=phase>=3?owned.w:barW,hh=phase>=3?owned.h:h; + const depthX=Math.min(w/3,mix(dx,mobile?4:8,morph)),depthY=mix(dy,mobile?3:6,morph); const active=phase>=4&&chosen!==null,muted=active&&i!==chosen; attr(b.g,{opacity:muted?.49:1}); attr(b.front,{d:bevel(x,y,w,Math.max(.5,hh),Math.min(2,w/5))}); @@ -127,23 +129,27 @@ export function createStage(host){ const ox=xs[i]+barW+17,oy=base-ghostH,ey=base-h,travel=frame.reducedMotion?1:ease((pr-.12)/.65); attr(b.operationLine,{d:`M${ox-4} ${f(oy)}H${ox}V${f(ey)}H${ox-4}`,stroke:color}); attr(b.operationDot,{cx:ox,cy:mix(oy,ey,travel),fill:color}); - const nx=xs[i]+barW/2;attr(b.number,{x:nx,y:base-h-18,opacity:chartOpacity});text(b.number,phase>=3?percent(P[i]):value(values[i])); + const nx=xs[i]+barW/2; + attr(b.number,{x:phase>=3?owned.valueX:nx,y:phase>=3?owned.valueY:base-h-18,opacity:1});text(b.number,phase>=3?percent(P[i]):value(values[i])); attr(b.original,{x:nx,y:base+22,opacity:phase===1?1:0});text(b.original,`z = ${frame.logits[i]}`); - const lx=mix(nx,bandX+bandW*(i+.5)/4,morph),ly=mix(base+(phase===1?53:48),bandY+bandH+69,morph); - attr(b.labelGroup,{transform:`translate(${f(lx)} ${f(ly)})`});attr(b.label,{x:0,y:0});attr(b.translation,{x:0,y:19});attr(b.dot,{cx:-(mobile?25:28),cy:-7}); - text(b.translation,isBand?percent(P[i]):CHINESE[i]); + const lx=phase>=3?owned.labelX:nx,ly=phase>=3?owned.labelY:base+(phase===1?53:48); + attr(b.labelGroup,{transform:`translate(${f(lx)} ${f(ly)})`});attr(b.label,{x:0,y:0});attr(b.translation,{x:0,y:19});attr(b.dot,{cx:-(mobile?29:35),cy:-7}); + attr(b.translation,{opacity:phase>=3?0:1});text(b.translation,CHINESE[i]); }); + attr(bandDock,{opacity:morph}); + attr(dockEdge,{d:bevel(bandX-6,bandY+bandH+1,bandW+12,12,2)}); + attr(dockLip,{d:`M${bandX-4} ${bandY+bandH+2}H${bandX+bandW+4}`}); attr(bandScale,{opacity:morph}); bandTicks.forEach((a,i)=>{const x=bandX+bandW*i/20;attr(a.tick,{x1:x,y1:bandY-18,x2:x,y2:bandY-(i%5===0?29:23)});if(a.label){attr(a.label,{x,y:bandY-38});text(a.label,phase>=4?(i/20).toFixed(i===0||i===20?0:2):`${i*5}%`);}}); bounds.forEach((p,i)=>{const x=bandX+cdf[i+1]*bandW;attr(p,{d:`M${f(x)} ${bandY+bandH+4}V${bandY+bandH+12}`});}); - attr(bandLeaders,{opacity:morph}); - labelLeaders.forEach((leader,i)=>{const sx=bandX+(cdf[i]+P[i]/2)*bandW,ex=bandX+bandW*(i+.5)/4,sy=bandY+bandH+7,ey=bandY+bandH+40;attr(leader,{d:`M${f(sx)} ${sy}C${f(sx)} ${sy+14},${f(ex)} ${ey-13},${f(ex)} ${ey}`,stroke:frame.color===false?'#a7b3c0':COLORS[i],opacity:.55});}); - const formulaY=mobile?378:365,fw=mobile?490:570; + attr(bandLeaders,{opacity:phase>=3?1:0}); + labelLeaders.forEach((leader,i)=>{const {x:sx,y:sy,endX:ex,endY:ey}=layout.candidates[i].leader;attr(leader,{d:`M${f(sx)} ${f(sy)}C${f(sx)} ${f(sy+9)},${f(ex)} ${f(ey-9)},${f(ex)} ${f(ey)}`,stroke:frame.color===false?'#a7b3c0':COLORS[i],opacity:.85});}); + const formulaY=mobile?378:365,fw=mobile?378:570; attr(formulaBack,{d:bevel((width-fw)/2,formulaY,fw,44,7)});attr(formulaBottom,{d:`M${(width-fw)/2+7} ${formulaY+47}H${(width+fw)/2-7}`});attr(formulaLabel,{x:width/2,y:formulaY+(phase===2?18:28)}); const sum=frame.weights.reduce((a,b)=>a+b,0),selected=chosen??0; const formulas=[`z = [ ${frame.logits.join(' , ')} ]`,`z / T T = ${T.toFixed(2)}`,`wᵢ = exp(zᵢ / T)`,`pᵢ = wᵢ / Σw Σp = 100%`,`u = ${frame.u.toFixed(3)} u ∈ [0, 1)`,`本次选择 ${TOKENS[selected]} · ${percent(P[selected])}`]; text(formulaLabel,formulas[phase]); - attr(weightScaleNote,{x:width/2,y:formulaY+35,opacity:phase===2?1:0});text(weightScaleNote,`高度按最大权重 ${value(max)} 缩放 · Σw = ${value(sum)}`); + attr(weightScaleNote,{x:width/2,y:formulaY+35,opacity:phase===2?1:0});text(weightScaleNote,mobile?`量程 ${value(max)} · Σw = ${value(sum)}`:`高度按最大权重 ${value(max)} 缩放 · Σw = ${value(sum)}`); const cursorTravel=phase>4?1:frame.reducedMotion?(pr>=.8?1:0):ease(pr/.8),cursorX=bandX+frame.u*bandW*cursorTravel; attr(cursorGroup,{opacity:phase===4?1:0});attr(cursorGlow,{x1:cursorX,y1:bandY-10,x2:cursorX,y2:bandY+bandH+8});attr(cursorLine,{x1:cursorX,y1:bandY-10,x2:cursorX,y2:bandY+bandH+8});attr(cursorHead,{d:poly([[cursorX-6,bandY-19],[cursorX+6,bandY-19],[cursorX+6,bandY-11],[cursorX,bandY-5],[cursorX-6,bandY-11]])}); attr(cursorReadout,{x:width/2,y:bandY-85,opacity:0});text(cursorReadout,chosen===null?'定位随机数':'已落入对应区间');attr(cursorNumber,{x:width/2,y:bandY-60,opacity:0});text(cursorNumber,chosen===null?`x = ${(frame.u*cursorTravel).toFixed(3)}`:`u = ${frame.u.toFixed(3)}`); @@ -154,7 +160,7 @@ export function createStage(host){ attr(resultShadow,{x:resultX-resultW/2+2,y:resultY+6,width:resultW,height:resultH}); attr(resultSide,{d:poly([[resultX-resultW/2,resultY+resultH-5],[resultX+resultW/2,resultY+resultH-5],[resultX+resultW/2+7,resultY+resultH-12],[resultX+resultW/2+7,resultY+resultH-4],[resultX+resultW/2,resultY+resultH+3],[resultX-resultW/2,resultY+resultH+3]])}); attr(resultPlate,{x:resultX-resultW/2,y:resultY,width:resultW,height:resultH});attr(resultAccent,{x:resultX-resultW/2+15,y:resultY+12,width:resultW-30,fill:COLORS[selected]});attr(resultToken,{x:resultX,y:resultY+43});text(resultToken,TOKENS[selected]);attr(resultProbability,{x:resultX,y:resultY+62});text(resultProbability,`${CHINESE[selected]} · ${percent(P[selected])}`);attr(resultTitle,{x:resultX,y:resultY-13});text(resultTitle,'SELECTED TOKEN'); - anchors={scores:[xs[0]+barW*.5,base-frame.logits[0]/4*plotH*.72],temperature:[xs[0]+barW+17,base-frame.scaled[0]/8*plotH*.72],weights:[xs[0]+barW/2,base-plotH*.7],probability:morph>.5?[bandX+P[0]*bandW*.5,bandY+bandH/2]:[xs[0]+barW/2,base-P[0]*plotH*.7],cursor:[cursorX,bandY+bandH/2],sampling:[cursorX,bandY+bandH/2],result:[resultX,resultY+12]}; + anchors={scores:[xs[0]+barW*.5,base-frame.logits[0]/4*plotH*.72],temperature:[xs[0]+barW+17,base-frame.scaled[0]/8*plotH*.72],weights:[xs[0]+barW/2,base-plotH*.7],probability:[layout.candidates[0].focus.x,layout.candidates[0].focus.y],cursor:[cursorX,bandY+bandH/2],sampling:[cursorX,bandY+bandH/2],result:[resultX,resultY+12]}; const spoken=phase<3?TOKENS.map((token,i)=>`${token} ${phase===0?'原始分数':phase===1?'缩放分数':'指数权重'} ${value(values[i])}`).join(','):TOKENS.map((token,i)=>`${token} 概率 ${percent(P[i])}`).join(','); text(desc,`阶段 ${phase+1}。温度 ${T.toFixed(2)}。${spoken}。${chosen===null?'尚未完成采样。':`本次选中 ${TOKENS[chosen]}。`}`); } diff --git a/apps/site/learn/token-choice/style.css b/apps/site/learn/token-choice/style.css index ef60d00..721f215 100644 --- a/apps/site/learn/token-choice/style.css +++ b/apps/site/learn/token-choice/style.css @@ -11,3 +11,8 @@ dialog{border:1px solid #e5dce9;background:#fffdf8;border-radius:18px;max-width: .challenge-answers{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:20px 0}.challenge-answers button{background:#f1ebf5;color:#725389;border:1px solid #dfd3e8;border-radius:8px;padding:13px 8px;font:20px Georgia,serif}.challenge-answers button[aria-pressed=true]{background:#8b749e;color:white;border-color:#8b749e}#challenge-feedback:empty{display:none}#challenge-feedback{padding:15px;background:#f2f1ed;border-radius:8px;color:#665873;line-height:1.9}.stage-actions #challenge{color:#80609e} .is-playing #challenge{display:none} + +/* Reserve real drawing space: a narrow screen must not shrink key type to 9px. + Initial settings may scroll; the playing stage retains pause and progress. */ +.exhibit{min-height:610px} +@media(max-width:700px){.exhibit{min-height:610px}.callout p{font-size:13px}.callout>span,.calculation{font-size:11px}.artwork{width:100%}} diff --git a/docs/ai-learning/STATUS.md b/docs/ai-learning/STATUS.md index c876edf..05fda83 100644 --- a/docs/ai-learning/STATUS.md +++ b/docs/ai-learning/STATUS.md @@ -4,7 +4,7 @@ Updated: 2026-10-28 (Asia/Shanghai). Current total: **4 / 10 published**. **Visual acceptance reopened for all four on 2026-10-28 after user feedback.** Active work: **Token choice quality rework**, starting with misbound probability labels at 32 seconds. New topics, including Transformer, are on hold until the four-scene rework queue passes the updated review gates. -See [Anatomy comparison and concrete findings](reviews/2026-10-28-anatomy-quality.md). Rework order: token-choice → attention → tokenization → embedding. Keep existing routes and mathematical/release evidence. Publication status does not mean the renewed visual gate has passed. This review changes no website implementation or distributed Skill. +See [Anatomy comparison and concrete findings](reviews/2026-10-28-anatomy-quality.md). Rework order: token-choice → attention → tokenization → embedding. Keep existing routes and mathematical/release evidence. Publication status does not mean the renewed visual gate has passed. The initial comparison changed no website implementation or distributed Skill. A subsequent token-choice repair exists only on the draft branch described below. Historical “Next” statements below describe the release sequence at that time and are superseded by this active work item and roadmap. @@ -44,3 +44,7 @@ Route `/learn/embedding/`. One question: how an integer ID retrieves one row fro ## Published lesson 03: Attention — 2026-10-28 Single causal attention row at C: authored Q/K/V, scaled dot products, future mask, exponential normalization, weighted V and sum. Query direction changes output (4.248 / 10 / 15.752); masked future V leaves output invariant. Tests and actual desktop/narrow-browser teaching review passed as detailed in LESSON.md. Published at https://explain.funagent.app/learn/attention/ . PR #4 passed CI 40562980763 and READY preview dpl_8fpzGGqXyoq2sbd7jDRdFDc2k5hV; fetched preview HTML/app/stage matched reviewed source exactly. Merge 49086e255b9527202f467103d7d0353b81627632 reached production READY as dpl_H4cKbv114YSRUKfzEGFXcdUXfE9P. Production browser verified future V=1000 leaves output 15.752, query zero produces 10, and prediction feedback/return preserves that state. No new Skill or host-compatibility claim; uses the shared playback, annotation and evidence method. Next after acceptance: Transformer layer. + +## Token-choice repair candidate — 2026-10-28 + +Draft branch `fix/token-choice-morph-craft-20261028` repairs moving-label ownership, makes the focus continuous, and drafts narrow-layout/carrier refinements. `npm run check` and3,620 geometric poses pass. Browser bootstrap returned Unknown tool; actual1×/4×/intermediate/390px visual and lifecycle acceptance remain pending. **No production update; visual acceptance remains needs-rework and token-choice stays active.** See [candidate evidence and exact pending checks](reviews/2026-10-28-token-choice-rework.md). Skill changes and new topics remain on hold. diff --git a/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md b/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md new file mode 100644 index 0000000..975601d --- /dev/null +++ b/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md @@ -0,0 +1,32 @@ +# Token choice rework candidate — 2026-10-28 + +Status: **implementation draft; NOT visually accepted, merged or published**. Base production/main: `0a3781278936c57f63de88dd9ab207fd1605dd2f`. All four published scenes retain `needs-rework`. This candidate is one step in token-choice rework, not a claim of Anatomy-level completion. + +## Implemented changes + +- Probability values no longer remain above the old bar positions while the rectangles move. From the probability chapter onward, candidate name and probability share one ordered identity lane. A color-matched line starts at that candidate's current front-face center/bottom and ends just above its identity. This remains meaningful for very narrow intervals. +- A pure geometry sampler owns the probability front faces, numeric-label positions, connectors and focus. The callout anchor follows a continuous point inside the moving blue face; it no longer switches between two anchor formulas at morph=.5. +- The interval band gains a shallow supporting edge; its actual widths remain probability-proportional. Extrusion shrinks with narrow interval width so depth does not overwhelm a tiny probability. These are drafted refinements, not browser-observed craft evidence. +- Narrow layout is recomposed to a 390-unit view rather than compressing 560 units; active value type remains 18 units and supporting type 16. Extra vertical drawing space is reserved. Initial settings may require vertical scrolling: the real 390px fit, active type size, viewport-height behavior and playing layout still require browser measurement. Do not infer legibility merely from declared font size. +- Narration now names the same-color correspondence and the height-to-width encoding. The interpretation is a change of representation, not probability changing during the morph. + +## Checks actually run + +`npm run check` passed, including existing independent mathematical golden values, all four AI scene tests, 721 planetary constraints and the site build. Added geometry invariants examine 3,620 poses: desktop/narrow, T=.4/.8/1/1.6/2, normal/reduced motion, 181 times between27s and36s per combination. They check disjoint front faces, values below every face, connector ownership, focus containment/continuity, exact final CDF positions and widths, and deterministic reverse seeking. Explicit default32s regression included. + +These are numerical/geometric checks, **not browser screenshots, user study results or actual device evidence**. They do not certify font metrics, painted stacking, connector collisions, reduced-motion preference handling or UI lifecycle. + +## Why the candidate remains a draft + +The Browser plugin was discovered and its prescribed bootstrap attempted. It returned `Unknown tool(browser.js)`. No CUA browser surface was exposed in this run. The managed preview instructions prohibit improvising a shell browser. No preview server, screenshot or browser acceptance is claimed. This is an environment verification limitation, not a permission request. + +Pending before merge: + +1. Actually inspect defaultT=.8 at27,29,30,31,32,33,34,36s and the reverse sequence; repeatT=.4 and2, including smallsofa intervals. Inspect line routing, neighboring labels and pale-edge contrast. +2. Capture actual1× whole stage and meaningful4× detail with no substitute generated imagery. Check the added carrier, bevels, contacts, occlusion and ownership during movement. +3. Check390px viewport: read every active number and formula, measure effective CSS font size, verify no clipped axis maximum and inspect the scrolling tradeoff. Review desktop diagram size as well. +4. Exercise play/pause/resume/seek/replay/completion, temperature changes, keyboard, reduced-motion and hidden-tab behavior. Preserve the fixedu counterfactual T=.8→mat / T=2→floor and prediction check. +5. Continue causal refinements where needed: earlier temperature/exponent/normalization transitions are still phase-based. This candidate does not close the entire continuous-causality review. +6. Check protected branch preview; only after all applicable review gates pass, merge and verify matching production SHA/READY/domain. + +No Skill distribution changed. Proven methods may be propagated after real visual verification through skill-creator, without overwriting unrelated personal Skill changes. No additional theme has started. diff --git a/docs/ai-learning/roadmap.json b/docs/ai-learning/roadmap.json index 6751ef1..e030ba1 100644 --- a/docs/ai-learning/roadmap.json +++ b/docs/ai-learning/roadmap.json @@ -153,6 +153,13 @@ "tokenization", "embedding" ], - "resumeAfter": "All four published scenes pass the reopened craft and causal-motion gates." + "resumeAfter": "All four published scenes pass the reopened craft and causal-motion gates.", + "candidate": { + "scene": "token-choice", + "branch": "fix/token-choice-morph-craft-20261028", + "status": "draft-awaiting-browser-review", + "record": "docs/ai-learning/reviews/2026-10-28-token-choice-rework.md", + "productionChanged": false + } } } diff --git a/package.json b/package.json index 3e1cbe1..6323817 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "build": "node scripts/build.mjs", - "test": "node evals/verify.mjs && node apps/site/learn/token-choice/model.test.mjs && node evals/verify-token-choice.mjs && node evals/verify-course.mjs && node apps/site/learn/tokenization/model.test.mjs && node apps/site/learn/embedding/model.test.mjs && node apps/site/learn/attention/model.test.mjs", + "test": "node evals/verify.mjs && node apps/site/learn/token-choice/model.test.mjs && node apps/site/learn/token-choice/geometry.test.mjs && node evals/verify-token-choice.mjs && node evals/verify-course.mjs && node apps/site/learn/tokenization/model.test.mjs && node apps/site/learn/embedding/model.test.mjs && node apps/site/learn/attention/model.test.mjs", "check": "npm test && npm run build" }, "engines": { From e6b74581f6a126e1d0fca9e3b72fa615407c35c2 Mon Sep 17 00:00:00 2001 From: hash-panda <110599333+hash-panda@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:00:26 +0800 Subject: [PATCH 2/2] Polish token-choice operation flow and verify craft in actual browser --- apps/site/learn/token-choice/LESSON.md | 5 ++ apps/site/learn/token-choice/SCENE_SPEC.json | 7 +- apps/site/learn/token-choice/app.mjs | 4 +- apps/site/learn/token-choice/geometry.mjs | 7 +- .../site/learn/token-choice/geometry.test.mjs | 22 +++++- apps/site/learn/token-choice/index.html | 2 +- apps/site/learn/token-choice/model.mjs | 13 +++- apps/site/learn/token-choice/stage.mjs | 63 ++++++++++++++---- apps/site/learn/token-choice/style.css | 2 + docs/ai-learning/STATUS.md | 7 +- .../reviews/2026-10-28-token-choice-rework.md | 40 +++++++++++ .../2026-10-28-token-choice/desktop-32.jpg | Bin 0 -> 60184 bytes .../desktop-result.jpg | Bin 0 -> 59309 bytes .../detail-4x-fixed.jpg | Bin 0 -> 36390 bytes .../2026-10-28-token-choice/mobile-32.jpg | Bin 0 -> 50640 bytes docs/ai-learning/roadmap.json | 9 +-- evals/browser/token-choice-review.html | 5 ++ 17 files changed, 158 insertions(+), 28 deletions(-) create mode 100644 docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-32.jpg create mode 100644 docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-result.jpg create mode 100644 docs/ai-learning/reviews/assets/2026-10-28-token-choice/detail-4x-fixed.jpg create mode 100644 docs/ai-learning/reviews/assets/2026-10-28-token-choice/mobile-32.jpg create mode 100644 evals/browser/token-choice-review.html diff --git a/apps/site/learn/token-choice/LESSON.md b/apps/site/learn/token-choice/LESSON.md index c91767b..f3f7b96 100644 --- a/apps/site/learn/token-choice/LESSON.md +++ b/apps/site/learn/token-choice/LESSON.md @@ -71,3 +71,8 @@ node apps/site/learn/token-choice/model.test.mjs ## Reopened visual review: draft repair — 2026-10-28 The 32s probability-label defect has a source-level repair using shared geometry and ordered identity lanes. Numerical ownership/non-overlap/CDF/continuous-focus/reverse-seek checks cover3,620 poses. Full site checks pass. See `docs/ai-learning/reviews/2026-10-28-token-choice-rework.md` for precise changes and remaining gates. Browser connection was unavailable; no actual screenshots,390px legibility,lifecycle or4× craft acceptance were performed for this candidate. It is not published or visually accepted. Earlier published evidence remains historical and does not validate this new code. + + +## Follow-up visual and teaching review — 2026-10-28 + +Browser access was restored. Implemented exact operation rail, staged scale visibility, larger narrow type, continuous annotations and carrier contact repair. Actual desktop/390px and native4× review, forward/reverse intermediate frames, natural completion/replay/Escape, controlled hidden event and manual reduced-motion setting were exercised. Prediction check retained fixedu and returnedT=2/floor27.6%. See `docs/ai-learning/reviews/2026-10-28-token-choice-rework.md` for observed results/screenshots and untested limits. The initial draft's no-browser statement is historical. This is developer review, not measured learning gains or external aesthetic endorsement. diff --git a/apps/site/learn/token-choice/SCENE_SPEC.json b/apps/site/learn/token-choice/SCENE_SPEC.json index 8047064..6e45b1b 100644 --- a/apps/site/learn/token-choice/SCENE_SPEC.json +++ b/apps/site/learn/token-choice/SCENE_SPEC.json @@ -119,7 +119,8 @@ "numericState": "所有数值从同一组输入计算,几何变形插值不改变它们的数学定义", "playback": "实际 elapsed time,支持暂停、继续、反向拖动、重播与结束恢复;隐藏标签页暂停", "narration": "每次仅一条气泡跟随当前数学对象;颜色在所有阶段保持候选身份一致", - "probabilityMorph": "chartBandGeometry drives front faces, identity-lane values, connectors and continuous focus. During representation change, widths/heights are transitional; final band width encodes probability." + "probabilityMorph": "chartBandGeometry drives front faces, identity-lane values, connectors and continuous focus. During representation change, widths/heights are transitional; final band width encodes probability.", + "operationRail": "Exact operand/operator/result pointers, one candidate at a time; travel is pedagogical, not compute latency. Chapter units switch discretely." }, "invariants": [ "四个概率均为正且总和约为 1", @@ -131,7 +132,9 @@ "对返回数组的修改不会污染后续 sample 或原始教学数据", "Probability labels stay below all moving front faces and retain one ordered candidate identity lane", "Probability connectors originate at their owning current front face; focus remains within that face", - "Final front-face band widths and cumulative positions equal p and cdf without extrusion" + "Final front-face band widths and cumulative positions equal p and cdf without extrusion", + "Carrier follows the shared bottom plane and never crosses the current fronts", + "Operation rail operands and outputs obey the selected candidate equation exactly" ], "simplifications": [ "四个词构成完整的教学词表;不是从真实模型词表截取的前四项,也不是线上模型输出", diff --git a/apps/site/learn/token-choice/app.mjs b/apps/site/learn/token-choice/app.mjs index cbf0907..dacfd32 100644 --- a/apps/site/learn/token-choice/app.mjs +++ b/apps/site/learn/token-choice/app.mjs @@ -9,7 +9,7 @@ const percent=x=>x>0&&x<.001?'<0.1':(x*100).toFixed(1); const number=x=>x.toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2}); function focus(on){app.classList.toggle('is-playing',on);$$('.secondary').forEach(el=>{el.inert=on;el.setAttribute('aria-hidden',String(on));});} function anchor(id){const outerRect=box.getBoundingClientRect(),bubbleRect=bubble.getBoundingClientRect();const top=Math.max(185,bubbleRect.bottom-outerRect.top+13);art.style.top=top+'px';const point=stage.projectAnchor(id);if(!point||!point.visible)return;const outer=box.getBoundingClientRect(),inner=art.getBoundingClientRect(),x=inner.left-outer.left+point.x*inner.width,y=inner.top-outer.top+point.y*inner.height;const half=bubble.offsetWidth/2,cx=Math.max(half+17,Math.min(outer.width-half-17,x));bubble.style.left=cx+'px';const sy=bubble.getBoundingClientRect().bottom-outer.top;$('#leader').setAttribute('viewBox',`0 0 ${outer.width} ${outer.height}`);$('#leader-line').setAttribute('d',`M${cx} ${sy} C${cx} ${sy+20},${x} ${Math.max(sy+20,y-24)},${x} ${y-8}`);$('#leader-dot').setAttribute('cx',x);$('#leader-dot').setAttribute('cy',y);} -function render(){if(disposed)return;const frame=sample(time,settings());frame.reducedMotion=motion.matches;stage.render(frame);const copy=narration(frame),key=JSON.stringify(copy);if(key!==lastCopy){lastCopy=key;$('#copy-eyebrow').textContent=copy.eyebrow;$('#copy-title').textContent=copy.title;$('#copy-body').textContent=copy.body;} +function render(){if(disposed)return;const frame=sample(time,settings());frame.reducedMotion=motion.matches||$('#reduce-motion').checked;app.classList.toggle('reduce-motion',frame.reducedMotion);stage.render(frame);const copy=narration(frame),key=JSON.stringify(copy);if(key!==lastCopy){lastCopy=key;$('#copy-eyebrow').textContent=copy.eyebrow;$('#copy-title').textContent=copy.title;$('#copy-body').textContent=copy.body;} $('#phase-label').textContent=`0${frame.phase+1} / 06 · ${phaseNames[frame.phase]}`;$('#live-temperature').textContent=`T = ${temperature.toFixed(2)}`; $('#temperature').value=temperature;$('#temperature-value').textContent=temperature.toFixed(2);$('#temperature').style.setProperty('--fill',((temperature-.4)/1.6*100)+'%'); $$('[data-temperature]').forEach(button=>button.setAttribute('aria-pressed',String(Math.abs(+button.dataset.temperature-temperature)<.001))); @@ -40,5 +40,5 @@ $$('[data-answer]').forEach(button=>button.onclick=()=>{const frame=sample(DURAT $('#challenge-try').onclick=()=>{$('#challenge-dialog').close();temperature=2;draw=0;time=DURATION;render();};$('#close-challenge').onclick=()=>$('#challenge-dialog').close(); $('#about').onclick=()=>{stop();$('#info').showModal();};$('#close-about').onclick=()=>$('#info').close();$('#close-calculation').onclick=()=>$('#calculation-dialog').close(); document.addEventListener('visibilitychange',()=>{if(document.hidden&&playing)stop();});document.addEventListener('keydown',e=>{if($('#info').open||$('#calculation-dialog').open||$('#challenge-dialog').open)return;if(e.key==='Escape'){stop();return;}if(e.code==='Space'&&!['INPUT','BUTTON','A'].includes(e.target.tagName)){e.preventDefault();play();}}); -motion.addEventListener('change',render);const resize=new ResizeObserver(()=>{stage.resize();anchor(sample(time,settings()).focus);});resize.observe(art);box.addEventListener('transitionend',()=>anchor(sample(time,settings()).focus)); +$('#reduce-motion').onchange=render;motion.addEventListener('change',render);const resize=new ResizeObserver(()=>{stage.resize();anchor(sample(time,settings()).focus);});resize.observe(art);box.addEventListener('transitionend',()=>anchor(sample(time,settings()).focus)); window.addEventListener('pagehide',event=>{if(event.persisted){stop();return;}disposed=true;playing=false;cancelAnimationFrame(raf);stage.dispose();resize.disconnect();motion.removeEventListener('change',render);});render(); diff --git a/apps/site/learn/token-choice/geometry.mjs b/apps/site/learn/token-choice/geometry.mjs index 6b63321..ae27c4b 100644 --- a/apps/site/learn/token-choice/geometry.mjs +++ b/apps/site/learn/token-choice/geometry.mjs @@ -4,7 +4,7 @@ const ease = x => { x = clamp(x); return x*x*(3-2*x); }; const mix = (a,b,t) => a+(b-a)*t; export function chartBandGeometry(frame, mobile=false) { const width=mobile?390:1000, height=mobile?430:420; - const base=mobile?280:285, plotH=mobile?204:225, barW=mobile?32:110; + const base=mobile?280:285, plotH=mobile?170:185, barW=mobile?32:110; const xs=mobile?[75,153,231,309]:[130,345,560,775]; const bandX=mobile?25:110, bandW=mobile?340:780, bandY=170, bandH=mobile?60:72; let morph=frame.phase>3?1:frame.phase===3?ease((frame.progress-.27)/.46):0; @@ -20,5 +20,8 @@ export function chartBandGeometry(frame, mobile=false) { leader:{x:x+w/2,y:y+height+3,endX:labelX,endY:labelY-21}, focus:{x:x+w/2,y:y+height*.3}}; }); - return {width,height,base,plotH,barW,xs,bandX,bandW,bandY,bandH,morph,candidates}; + const focusT=frame.phase>3?1:frame.reducedMotion?(frame.progress>=.27?1:0):ease((frame.progress-.20)/.15); + const annotation={x:mix(width/2,candidates[0].focus.x,focusT),y:mix(33,candidates[0].focus.y,focusT)}; + const dock={x:candidates[0].x-6,y:candidates[0].y+candidates[0].h+1,end:candidates[3].x+candidates[3].w+6}; + return {width,height,base,plotH,barW,xs,bandX,bandW,bandY,bandH,morph,candidates,annotation,dock}; } diff --git a/apps/site/learn/token-choice/geometry.test.mjs b/apps/site/learn/token-choice/geometry.test.mjs index a5637b9..e66daee 100644 --- a/apps/site/learn/token-choice/geometry.test.mjs +++ b/apps/site/learn/token-choice/geometry.test.mjs @@ -1,5 +1,5 @@ import assert from 'node:assert/strict'; -import {sample} from './model.mjs'; +import {sample,operation} from './model.mjs'; import {chartBandGeometry} from './geometry.mjs'; const close=(a,b,t=1e-8)=>assert.ok(Math.abs(a-b){ assert.ok(c.w>0&&c.h>0); + close(g.dock.y,c.y+c.h+1);assert.ok(g.dock.xc.x+c.w,'carrier spans all four fronts without intersecting them'); assert.ok(c.x>=0&&c.x+c.w<=g.width); if(i<3)assert.ok(c.x+c.w<=g.candidates[i+1].x+1e-8,'front faces must not overlap'); // Every number stays in a readable identity lane BELOW all candidate faces. @@ -37,3 +38,22 @@ const mid=chartBandGeometry(sample(32),false),floor=mid.candidates[1]; assert.ok(floor.valueY>mid.candidates[0].y+mid.candidates[0].h); assert.ok(floor.valueX>mid.candidates[0].valueX); console.log(`Token choice geometry: ${checked} intermediate poses; ownership, non-overlap, CDF scale, continuous focus, reverse seek passed. Browser visual acceptance remains separate.`); + +for(const temperature of [.4,.8,2])for(const phase of [1,2,3])for(const progress of [0,.05,.2499,.25,.50,.7499,.99,1]){ + const starts=[0,8,18,27,36,45],t=starts[phase]+progress*(starts[phase+1]-starts[phase]); + const frame={...sample(t,{temperature}),phase,progress}; + const op=operation(frame),i=op.candidate; + assert.ok(i>=0&&i<4&&op.progress>=0&&op.progress<=1); + if(phase===1)close(op.output,op.input/temperature); + if(phase===2)close(op.output,Math.exp(op.input)); + if(phase===3)close(op.output,op.input/frame.totalWeight); +} +for(const mobile of [false,true]){ + let previous=null; + for(let i=0;i<=900;i++){ + const g=chartBandGeometry(sample(27+i/100),mobile); + if(previous)assert.ok(Math.hypot(g.annotation.x-previous.x,g.annotation.y-previous.y)<5,'rail-to-face annotation jump'); + previous=g.annotation; + } +} +console.log('Exact operation operands/results and rail-to-face annotation continuity passed.'); diff --git a/apps/site/learn/token-choice/index.html b/apps/site/learn/token-choice/index.html index dc1501d..bf54d29 100644 --- a/apps/site/learn/token-choice/index.html +++ b/apps/site/learn/token-choice/index.html @@ -9,5 +9,5 @@
Explain3D · 数学图解实验教学数据 · 实时计算 · 可暂停检查

FOLLOW THE NUMBERS

跟着同一个词,走完计算。

候选原始分数 zz / T指数权重概率

这 4 个候选构成完整的教学词表;分数由示例设定,未调用真实语言模型。每个候选按一个教学 Token 处理。现实模型的词表与分词方式更复杂。

-

A SMALL, COMPLETE EXPLANATION

看清一次选择是怎么发生的。

这节课从模型已经给出候选分数的位置开始,演示温度缩放、指数运算、概率归一化与随机采样。图形只表达这些数学关系。

输入固定为 the cat sat on the …,4 个教学候选为 mat、floor、bed、sofa,原始分数为 3、2、1、0。这里只完成一次选择,不把结果接回上下文继续生成。

温度改变分布的集中程度;较高温度不意味着答案更正确。抽样使用可复现的均匀随机数,游标移动用来展示已确定的落点。重复抽样也可能选中同一个词。

本版保留上一版参考 Anatomy 的细线、浅色阶与轻立体风格,重新绘制数学图形,没有复用轮盘主体。查看视觉参考 ↗

浏览器内实时计算 · SVG 矢量绘制 · 支持减少动态效果 · 本版讲解为同步文字气泡,无语音

+

A SMALL, COMPLETE EXPLANATION

看清一次选择是怎么发生的。

这节课从模型已经给出候选分数的位置开始,演示温度缩放、指数运算、概率归一化与随机采样。图形只表达这些数学关系。

输入固定为 the cat sat on the …,4 个教学候选为 mat、floor、bed、sofa,原始分数为 3、2、1、0。这里只完成一次选择,不把结果接回上下文继续生成。

温度改变分布的集中程度;较高温度不意味着答案更正确。抽样使用可复现的均匀随机数,游标移动用来展示已确定的落点。重复抽样也可能选中同一个词。

本版保留上一版参考 Anatomy 的细线、浅色阶与轻立体风格,重新绘制数学图形,没有复用轮盘主体。查看视觉参考 ↗

运算轨迹是讲解指针,不表示真实计算耗时;变形只是改变表示方式。未调用真实模型。

浏览器内实时计算 · SVG 矢量绘制 · 支持减少动态效果 · 本版讲解为同步文字气泡,无语音

PREDICT · TRY · EXPLAIN

先预测,再看发生了什么。

固定分数 [3, 2, 1, 0] 和随机数 u = 0.6219。T = 0.8 时选中了 mat。现在把温度提高到 2.0,这次会选中哪个候选?

检验的是分布与随机数的关系;一次选择不会因为温度高就自动更正确。

diff --git a/apps/site/learn/token-choice/model.mjs b/apps/site/learn/token-choice/model.mjs index 774a802..cfe2fe4 100644 --- a/apps/site/learn/token-choice/model.mjs +++ b/apps/site/learn/token-choice/model.mjs @@ -43,6 +43,17 @@ export function sample(time,{temperature=.8,seed=22,draw=0}={}){ return {time:t,phase,progress,...data,u,selected,focus:FOCUS[phase]}; } +// Reveals one exact operation at a time; travel is a teaching pointer, not compute latency. +export function operation(frame){ + const local=frame.phase===3?Math.min(1,frame.progress/.27):frame.progress; + const scaled=Math.min(3.999999,Math.max(0,local)*4),candidate=Math.floor(scaled),progress=scaled-candidate; + const i=candidate; + if(frame.phase===1)return {candidate,progress,input:frame.logits[i],operator:`÷ ${frame.temperature.toFixed(2)}`,output:frame.scaled[i]}; + if(frame.phase===2)return {candidate,progress,input:frame.scaled[i],operator:'exp',output:frame.weights[i]}; + if(frame.phase===3)return {candidate,progress,input:frame.weights[i],operator:`÷ ${frame.totalWeight.toFixed(2)}`,output:frame.p[i]}; + return null; +} + const number=value=>value.toFixed(2).replace(/\.00$/,''); const percent=value=>value>0&&value<.001?'<0.1':(value*100).toFixed(1); @@ -53,7 +64,7 @@ export function narration(frame){ {eyebrow:'看这里 · 候选分数',title:'先有分数,还没有概率。',body:'同一个输入,四个候选各有一个分数。数值越大,倾向越强;它们还不是百分比。',formula:'教学分数 z = [3, 2, 1, 0]'}, {eyebrow:'看这里 · 温度缩放',title:'除以温度,改变分数之间的差距。',body:`原始分数保持不变。T = ${t} 时,相邻候选的分差从 1 变为 ${number(1/temperature)}。`,formula:`3 ÷ ${t} = ${number(scaled[0])};2 ÷ ${t} = ${number(scaled[1])}`}, {eyebrow:'看这里 · 指数权重',title:'取指数,让分差变成权重之比。',body:'每个数经过指数运算,得到一个正的权重。高分候选获得更多权重,此时总和还不是 1。',formula:`exp(${number(scaled[0])}) = ${number(weights[0])};权重总和 = ${number(totalWeight)}`}, - {eyebrow:'看这里 · 概率分布',title:frame.progress<.73?'每个权重除以总和,得到概率。':'除以总和,所有机会合成 100%。',body:frame.progress<.73?'同色连线始终连着同一个候选;数值不变,高度正变成区间宽度。':'四段合为 100%;区间越宽,被均匀随机数命中的机会越大。',formula:`P(mat) = ${number(weights[0])} ÷ ${number(totalWeight)} = ${percent(p[0])}%`}, + {eyebrow:'看这里 · 概率分布',title:frame.progress<.73?'每个权重除以总和,得到概率。':'除以总和,所有机会合成 100%。',body:frame.progress<.27?'每一项都除以同一个权重总和。运算条逐个对应四个候选。':frame.progress<.73?'同色连线始终连着同一个候选;数值不变,高度正变成区间宽度。':'四段合为 100%;区间越宽,被均匀随机数命中的机会越大。',formula:`P(mat) = ${number(weights[0])} ÷ ${number(totalWeight)} = ${percent(p[0])}%`}, {eyebrow:'看这里 · 随机数游标',title:selected===null?'一个随机数,落入一个概率区间。':`游标落定,选中了 ${TOKENS[selected]}。`,body:'先生成 0 到 1 之间的均匀随机数。游标展示它的位置,落入哪个区间,就选哪个候选。',formula:`u = ${u.toFixed(4)};选择满足 Cᵢ ≤ u < Cᵢ₊₁ 的候选`}, {eyebrow:'看这里 · 这次的选择',title:`这次得到 ${TOKENS[selected]??'一个候选'}。`,body:`${selected===null?'':ZH[selected]+' · 概率 '+percent(p[selected])+'%。'}同一个输入再抽一次,可能选到别的候选。`,formula:'固定上下文的一次采样 · 本节没有继续生成后续 Token'} ][phase]; diff --git a/apps/site/learn/token-choice/stage.mjs b/apps/site/learn/token-choice/stage.mjs index ae74c4a..b909eea 100644 --- a/apps/site/learn/token-choice/stage.mjs +++ b/apps/site/learn/token-choice/stage.mjs @@ -1,3 +1,4 @@ +import {operation as sampleOperation} from './model.mjs'; import {chartBandGeometry} from './geometry.mjs'; /** * A mathematical scene for Explain3D. Original vector geometry, inspired by @@ -19,18 +20,18 @@ const css=` svg{display:block;width:100%;height:100%;overflow:visible;contain:layout style} path,line,rect,circle{vector-effect:non-scaling-stroke} text{user-select:none;paint-order:stroke;stroke:none;text-rendering:geometricPrecision} - .axis{font:11px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#8290a1} + .axis{font:18px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#8290a1} .token{font:25px Georgia,"Times New Roman",serif;fill:#3a4657;letter-spacing:.1px} - .translation{font-size:11px;fill:#7e8795} + .translation{font-size:14px;fill:#7e8795} .number{font:18px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#485872;font-variant-numeric:tabular-nums} .note{font-size:12px;fill:#778292;letter-spacing:.15px} .formula{font:17px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#5a6680;font-variant-numeric:tabular-nums} - .small{font:11px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#8992a0} + .small{font:18px ui-monospace,SFMono-Regular,Consolas,monospace;fill:#8992a0} .fine{fill:none;stroke:#c3ccd5;stroke-width:.6;stroke-linecap:round;stroke-linejoin:round} .guide{fill:none;stroke:#b2bfce;stroke-width:.6;stroke-dasharray:2 4} .grid{stroke:#dfe5ea;stroke-width:.5} .bright{stroke:#fff;stroke-width:1;fill:none} - .mobile .axis{font-size:16px}.mobile .number{font-size:18px}.mobile .note{font-size:16px}.mobile .small{font-size:16px}.mobile .translation{font-size:16px}.mobile .token{font-size:22px}.mobile .formula{font-size:16px} + .mobile .axis{font-size:18px}.mobile .number{font-size:18px}.mobile .note{font-size:16px}.mobile .small{font-size:18px}.mobile .translation{font-size:16px}.mobile .token{font-size:22px}.mobile .formula{font-size:18px} `; function node(tag,attrs={},parent){const n=document.createElementNS(NS,tag);for(const[k,v]of Object.entries(attrs))n.setAttribute(k,String(v));parent?.append(n);return n;} @@ -48,7 +49,11 @@ export function createStage(host){ const floorGradient=node('linearGradient',{id:'tc-floor',x1:0,y1:0,x2:0,y2:1},defs);node('stop',{offset:0,'stop-color':'#fdfefe'},floorGradient);node('stop',{offset:1,'stop-color':'#edf1f4'},floorGradient); const goldGradient=node('linearGradient',{id:'tc-gold',x1:0,y1:0,x2:0,y2:1},defs);node('stop',{offset:0,'stop-color':'#f4d799'},goldGradient);node('stop',{offset:1,'stop-color':'#d7ac57'},goldGradient); const glow=node('filter',{id:'tc-shadow',x:'-40%',y:'-100%',width:'180%',height:'300%'},defs);node('feGaussianBlur',{stdDeviation:4},glow); - const gradients=COLORS.map((c,i)=>{const g=node('linearGradient',{id:`tc-bar-${i}`,x1:0,y1:0,x2:1,y2:0},defs);const a=node('stop',{offset:0,'stop-color':c,'stop-opacity':.48},g),b=node('stop',{offset:.83,'stop-color':c,'stop-opacity':.28},g);node('stop',{offset:1,'stop-color':'#fff','stop-opacity':.7},g);return[a,b];}); + const gradients=COLORS.map((c,i)=>{const g=node('linearGradient',{id:`tc-bar-${i}`,x1:0,y1:0,x2:1,y2:0},defs);const a=node('stop',{offset:0,'stop-color':c,'stop-opacity':.65},g),b=node('stop',{offset:.83,'stop-color':c,'stop-opacity':.42},g);node('stop',{offset:1,'stop-color':'#fff','stop-opacity':.4},g);return[a,b];}); + const operationRail=node('g',{'data-operation':'exact-values'},svg),railBody=node('path',{fill:'url(#tc-floor)',stroke:'#bcc8d4','stroke-width':.7},operationRail),railLower=node('path',{fill:'none',stroke:'#d4dce3','stroke-width':1},operationRail),railDivider=node('path',{class:'fine'},operationRail); + const railToken=node('text',{class:'token','text-anchor':'middle'},operationRail),railInput=node('text',{class:'number','text-anchor':'middle'},operationRail),railOperator=node('text',{class:'number','text-anchor':'middle'},operationRail),railOutput=node('text',{class:'number','text-anchor':'middle'},operationRail),railArrow1=node('text',{class:'number','text-anchor':'middle'},operationRail),railArrow2=node('text',{class:'number','text-anchor':'middle'},operationRail); + text(railArrow1,'→');text(railArrow2,'→'); + const railFlow=node('path',{fill:'none','stroke-width':.9,'stroke-dasharray':'2 4'},operationRail),railDot=node('circle',{r:3,stroke:'#fff','stroke-width':1},operationRail); const axisGroup=node('g',{},svg),axisTicks=[]; const plotBacking=node('path',{fill:'#f5f7f9',opacity:.6},axisGroup); const gridGroup=node('g',{},axisGroup); @@ -93,8 +98,9 @@ export function createStage(host){ const cdf=frame.cdf?.length===5?frame.cdf:[0,...P.map((_,i)=>P.slice(0,i+1).reduce((a,b)=>a+b,0))]; const chosen=frame.selected,dx=mobile?5:11,dy=mobile?4:8; const {base,plotH,barW,xs,bandX,bandW,bandY,bandH,morph}=layout; - const axisX=mobile?57:87,plotEnd=xs[3]+barW+dx; - const chartOpacity=1-morph; + const axisX=mobile?68:87,plotEnd=xs[3]+barW+dx; + const chartOpacity=1-ease(morph/.22); + const operation=sampleOperation(frame),showOperation=phase===1||phase===2||phase===3&&pr<.27; let values=frame.logits,max=4,axisTitle='原始分数 z'; if(phase===1){values=frame.scaled;max=8;axisTitle='缩放分数 z / T';} if(phase===2){values=frame.weights;max=Math.max(...values);axisTitle='指数权重 exp(z / T)';} @@ -102,7 +108,7 @@ export function createStage(host){ attr(axisGroup,{opacity:chartOpacity});attr(baseGroup,{opacity:chartOpacity}); attr(plotBacking,{d:poly([[axisX,base],[axisX,base-plotH],[plotEnd,base-plotH],[plotEnd,base]])}); attr(axisSpine,{d:`M${axisX} ${base-plotH-8}V${base}H${plotEnd+12}`}); - attr(axisName,{x:axisX,y:base-plotH-25});text(axisName,axisTitle); + attr(axisName,{x:plotEnd,y:base-plotH-13,'text-anchor':'end'});text(axisName,axisTitle); axisTicks.forEach((a,i)=>{const y=base-plotH*i/4;attr(a.line,{x1:axisX,y1:y,x2:plotEnd,y2:y});attr(a.tick,{x1:axisX-4,y1:y,x2:axisX,y2:y});attr(a.label,{x:axisX-12,y:y+4});text(a.label,phase>=3?`${i*25}%`:value(max*i/4));}); const bx=xs[0]-25,bw=plotEnd-bx+24,by=base+8; attr(baseShadow,{d:poly([[bx-6,by+12],[bx+bw+12,by+12],[bx+bw+19,by+26],[bx,by+26]])}); @@ -117,7 +123,8 @@ export function createStage(host){ const x=phase>=3?owned.x:xs[i],y=phase>=3?owned.y:base-h,w=phase>=3?owned.w:barW,hh=phase>=3?owned.h:h; const depthX=Math.min(w/3,mix(dx,mobile?4:8,morph)),depthY=mix(dy,mobile?3:6,morph); const active=phase>=4&&chosen!==null,muted=active&&i!==chosen; - attr(b.g,{opacity:muted?.49:1}); + attr(b.g,{opacity:muted?.72:1}); + attr(b.front,{'stroke-width':showOperation&&operation.candidate===i?1.3:.65}); attr(b.front,{d:bevel(x,y,w,Math.max(.5,hh),Math.min(2,w/5))}); attr(b.side,{d:poly([[x+w,y],[x+w+depthX,y-depthY],[x+w+depthX,y+hh-depthY],[x+w,y+hh]])}); attr(b.top,{d:poly([[x,y],[x+depthX,y-depthY],[x+w+depthX,y-depthY],[x+w,y]]),opacity:hh>.5?1:0}); @@ -137,13 +144,41 @@ export function createStage(host){ attr(b.translation,{opacity:phase>=3?0:1});text(b.translation,CHINESE[i]); }); attr(bandDock,{opacity:morph}); - attr(dockEdge,{d:bevel(bandX-6,bandY+bandH+1,bandW+12,12,2)}); - attr(dockLip,{d:`M${bandX-4} ${bandY+bandH+2}H${bandX+bandW+4}`}); - attr(bandScale,{opacity:morph}); + const {x:dockX,y:dockY,end:dockEnd}=layout.dock; + attr(dockEdge,{d:bevel(dockX,dockY,dockEnd-dockX,12,2)}); + attr(dockLip,{d:`M${dockX+2} ${dockY+1}H${dockEnd-2}`}); + attr(bandScale,{opacity:phase===5?0:ease((morph-.8)/.2)}); bandTicks.forEach((a,i)=>{const x=bandX+bandW*i/20;attr(a.tick,{x1:x,y1:bandY-18,x2:x,y2:bandY-(i%5===0?29:23)});if(a.label){attr(a.label,{x,y:bandY-38});text(a.label,phase>=4?(i/20).toFixed(i===0||i===20?0:2):`${i*5}%`);}}); bounds.forEach((p,i)=>{const x=bandX+cdf[i+1]*bandW;attr(p,{d:`M${f(x)} ${bandY+bandH+4}V${bandY+bandH+12}`});}); attr(bandLeaders,{opacity:phase>=3?1:0}); labelLeaders.forEach((leader,i)=>{const {x:sx,y:sy,endX:ex,endY:ey}=layout.candidates[i].leader;attr(leader,{d:`M${f(sx)} ${f(sy)}C${f(sx)} ${f(sy+9)},${f(ex)} ${f(ey-9)},${f(ex)} ${f(ey)}`,stroke:frame.color===false?'#a7b3c0':COLORS[i],opacity:.85});}); + attr(operationRail,{opacity:phase===3?1-ease((pr-.22)/.05):showOperation?1:0,'aria-hidden':String(!showOperation)}); + if(operation){ + const i=operation.candidate,c=COLORS[i],rw=mobile?374:650,rx=(width-rw)/2,ry=9; + attr(railBody,{d:bevel(rx,ry,rw,49,5)});attr(railLower,{d:`M${rx+5} 61H${rx+rw-5}`}); + const points=mobile?[rx+29,rx+88,rx+141,rx+210,rx+277,rx+329]:[rx+52,rx+155,rx+237,rx+325,rx+420,rx+538]; + const [tx,ix,a1x,ox,a2x,outx]=points; + attr(railToken,{x:tx,y:39,fill:c,'font-size':mobile?19:25});text(railToken,TOKENS[i]); + attr(railDivider,{d:`M${rx+(mobile?56:100)} 18V49`}); + attr(railInput,{x:ix,y:39});text(railInput,value(operation.input)); + attr(railOperator,{x:ox,y:39,fill:c});text(railOperator,operation.operator); + attr(railOutput,{x:outx,y:39,fill:c});text(railOutput,phase===3?percent(operation.output):value(operation.output)); + attr(railArrow1,{x:a1x,y:39});attr(railArrow2,{x:a2x,y:39}); + const targetX=xs[i]+barW/2,targetY=base-values[i]/max*plotH-30; + attr(railFlow,{d:`M${ix} 47H${outx}V73H${targetX}V${targetY}`,stroke:c}); + const travel=frame.reducedMotion?1:operation.progress; + let dotX,dotY; + if(travel<.65){dotX=mix(ix,outx,ease(travel/.65));dotY=47;} + else { + const path=[[outx,47],[outx,73],[targetX,73],[targetX,targetY]]; + const lengths=path.slice(1).map((p,j)=>Math.hypot(p[0]-path[j][0],p[1]-path[j][1])); + let distance=ease((travel-.65)/.35)*lengths.reduce((a,b)=>a+b,0),j=0; + while(jlengths[j])distance-=lengths[j++]; + const t=lengths[j]?distance/lengths[j]:1; + dotX=mix(path[j][0],path[j+1][0],t);dotY=mix(path[j][1],path[j+1][1],t); + } + attr(railDot,{cx:dotX,cy:dotY,fill:c}); + } const formulaY=mobile?378:365,fw=mobile?378:570; attr(formulaBack,{d:bevel((width-fw)/2,formulaY,fw,44,7)});attr(formulaBottom,{d:`M${(width-fw)/2+7} ${formulaY+47}H${(width+fw)/2-7}`});attr(formulaLabel,{x:width/2,y:formulaY+(phase===2?18:28)}); const sum=frame.weights.reduce((a,b)=>a+b,0),selected=chosen??0; @@ -159,8 +194,8 @@ export function createStage(host){ attr(resultLink,{d:`M${f(resultX)} ${f(resultY+resultH)}C${f(resultX)} ${f(resultY+resultH+12)},${f(segmentX)} ${bandY-16},${f(segmentX)} ${bandY+8}`}); attr(resultShadow,{x:resultX-resultW/2+2,y:resultY+6,width:resultW,height:resultH}); attr(resultSide,{d:poly([[resultX-resultW/2,resultY+resultH-5],[resultX+resultW/2,resultY+resultH-5],[resultX+resultW/2+7,resultY+resultH-12],[resultX+resultW/2+7,resultY+resultH-4],[resultX+resultW/2,resultY+resultH+3],[resultX-resultW/2,resultY+resultH+3]])}); - attr(resultPlate,{x:resultX-resultW/2,y:resultY,width:resultW,height:resultH});attr(resultAccent,{x:resultX-resultW/2+15,y:resultY+12,width:resultW-30,fill:COLORS[selected]});attr(resultToken,{x:resultX,y:resultY+43});text(resultToken,TOKENS[selected]);attr(resultProbability,{x:resultX,y:resultY+62});text(resultProbability,`${CHINESE[selected]} · ${percent(P[selected])}`);attr(resultTitle,{x:resultX,y:resultY-13});text(resultTitle,'SELECTED TOKEN'); - anchors={scores:[xs[0]+barW*.5,base-frame.logits[0]/4*plotH*.72],temperature:[xs[0]+barW+17,base-frame.scaled[0]/8*plotH*.72],weights:[xs[0]+barW/2,base-plotH*.7],probability:[layout.candidates[0].focus.x,layout.candidates[0].focus.y],cursor:[cursorX,bandY+bandH/2],sampling:[cursorX,bandY+bandH/2],result:[resultX,resultY+12]}; + attr(resultPlate,{x:resultX-resultW/2,y:resultY,width:resultW,height:resultH});attr(resultAccent,{x:resultX-resultW/2+15,y:resultY+12,width:resultW-30,fill:COLORS[selected]});attr(resultToken,{x:resultX,y:resultY+43});text(resultToken,TOKENS[selected]);attr(resultProbability,{x:resultX,y:resultY+62});text(resultProbability,`${CHINESE[selected]} · ${percent(P[selected])}`);attr(resultTitle,{x:resultX,y:resultY-13});text(resultTitle,'选中结果'); + anchors={scores:[xs[0]+barW*.5,base-frame.logits[0]/4*plotH*.72],temperature:[width/2,33],weights:[width/2,33],probability:[layout.annotation.x,layout.annotation.y],cursor:[cursorX,bandY+bandH/2],sampling:[cursorX,bandY+bandH/2],result:[resultX,resultY+12]}; const spoken=phase<3?TOKENS.map((token,i)=>`${token} ${phase===0?'原始分数':phase===1?'缩放分数':'指数权重'} ${value(values[i])}`).join(','):TOKENS.map((token,i)=>`${token} 概率 ${percent(P[i])}`).join(','); text(desc,`阶段 ${phase+1}。温度 ${T.toFixed(2)}。${spoken}。${chosen===null?'尚未完成采样。':`本次选中 ${TOKENS[chosen]}。`}`); } diff --git a/apps/site/learn/token-choice/style.css b/apps/site/learn/token-choice/style.css index 721f215..a2c55d6 100644 --- a/apps/site/learn/token-choice/style.css +++ b/apps/site/learn/token-choice/style.css @@ -16,3 +16,5 @@ dialog{border:1px solid #e5dce9;background:#fffdf8;border-radius:18px;max-width: Initial settings may scroll; the playing stage retains pause and progress. */ .exhibit{min-height:610px} @media(max-width:700px){.exhibit{min-height:610px}.callout p{font-size:13px}.callout>span,.calculation{font-size:11px}.artwork{width:100%}} + +.reduce-motion .secondary,.reduce-motion .artwork{transition:none!important} diff --git a/docs/ai-learning/STATUS.md b/docs/ai-learning/STATUS.md index 05fda83..0c6a7d6 100644 --- a/docs/ai-learning/STATUS.md +++ b/docs/ai-learning/STATUS.md @@ -2,7 +2,7 @@ Updated: 2026-10-28 (Asia/Shanghai). -Current total: **4 / 10 published**. **Visual acceptance reopened for all four on 2026-10-28 after user feedback.** Active work: **Token choice quality rework**, starting with misbound probability labels at 32 seconds. New topics, including Transformer, are on hold until the four-scene rework queue passes the updated review gates. +Current total: **4 / 10 published**. **Visual acceptance reopened for all four on 2026-10-28 after user feedback.** Token-choice follow-up has passed developer visual/teaching review and awaits the checked release; the other three remain open. Next rework: **Attention**. New topics, including Transformer, are on hold until the four-scene rework queue passes the updated review gates. See [Anatomy comparison and concrete findings](reviews/2026-10-28-anatomy-quality.md). Rework order: token-choice → attention → tokenization → embedding. Keep existing routes and mathematical/release evidence. Publication status does not mean the renewed visual gate has passed. The initial comparison changed no website implementation or distributed Skill. A subsequent token-choice repair exists only on the draft branch described below. @@ -48,3 +48,8 @@ Single causal attention row at C: authored Q/K/V, scaled dot products, future ma ## Token-choice repair candidate — 2026-10-28 Draft branch `fix/token-choice-morph-craft-20261028` repairs moving-label ownership, makes the focus continuous, and drafts narrow-layout/carrier refinements. `npm run check` and3,620 geometric poses pass. Browser bootstrap returned Unknown tool; actual1×/4×/intermediate/390px visual and lifecycle acceptance remain pending. **No production update; visual acceptance remains needs-rework and token-choice stays active.** See [candidate evidence and exact pending checks](reviews/2026-10-28-token-choice-rework.md). Skill changes and new topics remain on hold. + + +## Reviewed token-choice follow-up — 2026-10-28 + +Browser returned; actual intermediate/reverse desktop frames,390px, native4× contact detail, natural completion/replay, keyboard, manual reduced-motion and controlled hidden-event paths reviewed. Fixed newly observed carrier/front intersection and narrow tick clipping as well as the original label defect. Exact operation rail and staged scales improve causal inspection. Full check passed. Review decision closes listed token-choice defects, without asserting measured learning gains or awards; the other three scenes and Skill distribution alignment remain open. See [full follow-up record](reviews/2026-10-28-token-choice-rework.md). Deployment receipt follows only after matching production SHA/READY and route verification. diff --git a/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md b/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md index 975601d..d417d70 100644 --- a/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md +++ b/docs/ai-learning/reviews/2026-10-28-token-choice-rework.md @@ -30,3 +30,43 @@ Pending before merge: 6. Check protected branch preview; only after all applicable review gates pass, merge and verify matching production SHA/READY/domain. No Skill distribution changed. Proven methods may be propagated after real visual verification through skill-creator, without overwriting unrelated personal Skill changes. No additional theme has started. + + +## Follow-up implementation and real browser review — 2026-10-28 + +The cloud browser became available in the subsequent user-authorized session. The earlier draft-only record above is historical. This follow-up implemented and inspected the candidate; production receipt is recorded separately after deployment. + +### Changes beyond the draft + +- The temperature/exponent/normalization chapters now carry an exact operand → operator → result rail. A deterministic pointer travels along that operation and its connection to the corresponding candidate, in mat/floor/bed/sofa order. No interpolated/fictitious mathematical values are introduced. The diagram explicitly describes this as a teaching pointer, not hardware compute latency; chapter boundaries still switch units discretely. +- Retained aligned front-face quantitative lengths, shallow side faces, bevel edges, base contacts and identity colors. Removed old chart scales early in the morph and introduced cumulative ticks only when the band is almost settled. On the result pose the ruler is intentionally withdrawn to leave room for the lifted result card; candidate probabilities remain visible below. +- Actual4× inspection revealed that the added carrier crossed the translucent fronts during the morph. Fixed it to follow the shared bottom surface, and added a non-intersection/contact invariant. A low-temperature390px playback exposed clipped left tick text; moved the axis into its reserved margin and rechecked large values. +- Raised active type, used a390-unit narrow composition and reserved drawing height. Added a manual reduced-motion setting in the lesson explanation alongside the existing OS preference support. Initial narrow settings can require vertical scrolling; playing removes them and keeps the exhibit/pause/timeline in one screen. + +### Browser evidence actually observed + +Environment: current Chrome cloud browser, desktop screenshot1363×936, same-source390×844 iframe (not physical phone), plus1200px iframe rendered at native CSS zoom4× (not an upscaled raster). Read-only DOM geometry showed key18-unit numbers at about14.89 CSS px in the paused narrow exponent layout (SVG scale .82747),22-unit candidate names at18.20px. Playing uses the available larger drawing area. Source-distribution/physical phone/OS preference coverage is not inferred from these observations. + +| Check | Observed result | +|---|---| +| Forward morph | Actual paused27,29,30,31,32,33,34,36s frames inspected. Ordered values and color connectors retain their candidate ownership. No floor20.6% inside mat. | +| Reverse morph |36→32→29 inspected; corresponding geometry/labels returned to the same states. | +| Computation |8/12/20s rails show3÷.8=3.75,2÷.8=2.5,exp(3.75)=42.52, and normalization by59.19. Moving pointer remains on the drawn path. | +| Extremes |T=.4 band and tinysofa interval inspected, plusT=.4 exponent values up to1808 on narrow screen. FinalT=2 distribution and floor27.6% checked via prediction experiment. | +| Depth/detail |4× screenshot below shows front, top/side shading, bevel, carrier contact and identity connectors after the carrier repair. It is an inspectable mathematical exhibit, not a claim to match the part complexity of a physical watch. | +| Playback |Play/pause/resume exercised; progress moved with wall time and settings disappeared/reappeared. From49.5s natural completion reached50 and restored settings/quiz. Replay restarted near0; Escape paused. Home/End range keys and chapter stepping exercised. | +| Hidden |Controlled harness visibilitychange stopped playback at36.5s, restored settings and remained paused after visible event. This is an event-path test, not an OS tab-suspension or mobile backgrounding claim. | +| Reduced motion |Manual setting checked via actual dialog; subsequent seeking/chapter navigation used the reduced-motion branch. OS-level preference toggling not performed in this run. | +| Learning check |Narrow modal: wrongmat and correctfloor feedback inspected. Return-to-diagram preservedT=2,u=.6219,floor27.6%; explainsCDF boundaries .4551/.7311. | +| Model/site |npm run check passed: independent original golden values,3,620 geometry poses, exact operation equations, rail-anchor continuity, carrier contact, existing four-scene tests and721 planetary constraints. | + +![32-second whole-stage ownership](assets/2026-10-28-token-choice/desktop-32.jpg) +![Native4× detail after carrier repair](assets/2026-10-28-token-choice/detail-4x-fixed.jpg) +![390px intermediate frame](assets/2026-10-28-token-choice/mobile-32.jpg) +![Stable desktop result with ruler withdrawn](assets/2026-10-28-token-choice/desktop-result.jpg) + +### Teaching review decision + +This is developer teaching/visual review, not measured learning-effect research or user aesthetic approval. The bounded question remains how fixed scores and one fixed uniform sample produce one chosen candidate. The first view names the input/scores and makes score≠probability explicit; the operation rail links exact values to colors; the morph changes representation without changing probability; a fixed-u temperature experiment changes the selected result and explains why. Those observations close the listed token-choice ownership, narrow-readability, continuity and contact defects for this revision. The same benchmark is still open for Attention, tokenization and embedding; no new topic is authorized to bypass that queue. + +Limits: no real learner sessions, physical phones, screen readers, other browser engines, OS preference switching or hardware performance measurements. No award/equivalent-fidelity claim. Public/working Skill alignment remains a distinct pending task; this release does not claim a new installed or cross-host-verified Skill. diff --git a/docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-32.jpg b/docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-32.jpg new file mode 100644 index 0000000000000000000000000000000000000000..14a315df3ed12c9c946845e2af2a9e0ca5332051 GIT binary patch literal 60184 zcmeFZ2UwF&*C!lAQ4tFzAWi=U0SQe?KoG2iUIY?KLO>vZBoqaL(#3*wBoInyN>4(9 zlmr1mMS7Kz(5v*KfK)|U{!iPz_Ivl*eRkh(-}m~yXL4P4?#!HfX6`fR%$b?9qd=z}-Gb_wVV@VYVY2?8lBClp@an z*w_!T9pOC2b@<33_9MsG0c?lZ4|5;k;NiWXz<<-!%=|$-KB1cr2vUT>?H!JaDXBPn z`Gh8xluq7yo&8bZqOy0-ZHr@&C*rC(y{i&hj!&Nv%0A)h)($EcJZSaL^!IiTz7Hxt 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 J-$C4B{txv9VpaeE literal 0 HcmV?d00001 diff --git a/docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-result.jpg b/docs/ai-learning/reviews/assets/2026-10-28-token-choice/desktop-result.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f91ac239f3f84ab6154ac9f75604295373e3d2fd GIT binary patch literal 59309 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 ZTn0~`V`Nv+dxhacd`R4N!*spxKLABPgn9q~ literal 0 HcmV?d00001 diff --git a/docs/ai-learning/reviews/assets/2026-10-28-token-choice/detail-4x-fixed.jpg b/docs/ai-learning/reviews/assets/2026-10-28-token-choice/detail-4x-fixed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2ac3ffc29e1c46ffb44ec3286e2717d36d0b39b GIT binary patch literal 36390 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 literal 0 HcmV?d00001 diff --git a/docs/ai-learning/reviews/assets/2026-10-28-token-choice/mobile-32.jpg b/docs/ai-learning/reviews/assets/2026-10-28-token-choice/mobile-32.jpg new file mode 100644 index 0000000000000000000000000000000000000000..08bc3fc7fff12b10aaf67c71f2109d29db1e1ba3 GIT binary patch literal 50640 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 visual QA