Download source/src/DualScene.tsx from CladeTeam/ouroboros: direct link, hf CLI and curl.
- Browser
- Download file 14.1 kB
-
https://huggingface.co/spaces/CladeTeam/ouroboros/resolve/main/source/src/DualScene.tsx
- Command line
-
hf download hf://spaces/CladeTeam/ouroboros/source/src/DualScene.tsx
-
curl -L -o DualScene.tsx https://huggingface.co/spaces/CladeTeam/ouroboros/resolve/main/source/src/DualScene.tsx
14.1 kB
| import {useId} from 'react'; | |
| import config from '../t5config_large.json'; | |
| import {mix, phase, segment, windowAt, residuePreviewCount, sharingState} from './dualStory'; | |
| import type {Example} from './types'; | |
| const blue = '#397cbb', orange = '#cf643e', ink = '#24364a'; | |
| const words = (s:string) => s.replace(/([.!?])(?=[A-Z])/g,'$1 ').split(/\s+/); | |
| function wrap(s:string, limit:number) { | |
| const lines:string[] = []; let line = ''; | |
| words(s).forEach(word => { if ((line+' '+word).length > limit && line) { lines.push(line); line = word; } else line += (line?' ':'')+word; }); | |
| if (line) lines.push(line); | |
| return lines; | |
| } | |
| function Node({x,y,protein,decoder,focus,context=0,sharing=0}:{x:number;y:number;protein:boolean;decoder:boolean;focus:number;context?:number;sharing?:number}) { | |
| const color = protein?orange:blue; | |
| const rows = decoder?['Masked self-attention','Cross-attention','Feed-forward']:['Self-attention','Feed-forward']; | |
| return <g transform={`translate(${x} ${y})`} opacity={.24+.76*focus} data-module={`${protein?'protein':'text'}-${decoder?'decoder':'encoder'}`}> | |
| {[12,6].map(n=><rect key={n} x={n} y={-n} width={228-n} height="200" rx="12" fill="#f8fafc" stroke={color} strokeOpacity=".2"/>)} | |
| <rect width="228" height="200" rx="12" fill={protein?'#fff5ef':'#eff6fc'} stroke={color} strokeWidth={1+focus*.6}/> | |
| <text x="17" y="25" className="ds-micro" fill={color}>{decoder?'AUTOREGRESSIVE DECODER':'CONTEXTUAL ENCODER'}</text> | |
| <text x="17" y="54" className="ds-node-title" fill={ink}>{protein?'Protein':'Text'} {decoder?'Decoder':'Encoder'}</text> | |
| <text x="207" y="25" textAnchor="end" className="ds-count" fill={color}>×{decoder?config.num_decoder_layers:config.num_layers}</text> | |
| {rows.map((label,i)=>{ | |
| const rowY = 73+i*(decoder?34:51); | |
| return <g key={label} data-shared-attention={i===0?sharing.toFixed(4):undefined}> | |
| {i===0&&<rect x="9" y={rowY-5} width="210" height="37" rx="8" fill={color} fillOpacity={sharing*.1} stroke={color} strokeOpacity={sharing} strokeWidth={sharing*2.5}/>} | |
| <rect x="14" y={rowY} width="200" height="27" rx="5" fill={i===0&&sharing>.1?color:label==='Cross-attention'&&context>0?color:'#ffffff'} fillOpacity={i===0?.8-sharing*.66:label==='Cross-attention'? .14+.5*context:.8} stroke={color} strokeOpacity={label==='Cross-attention'?.5:.14}/> | |
| <text x="25" y={rowY+19} className="ds-row" fill={label==='Cross-attention'&&context>.65?'#fff':color}>{label}</text> | |
| {i===0&&<text x="204" y={rowY+18} textAnchor="end" className="ds-shared-tag" fill={color} opacity={sharing}>TIED</text>} | |
| </g>; | |
| })} | |
| <text x="17" y="190" className="ds-small" fill={color}>Block detail · d = {config.d_model.toLocaleString('en-US')}</text> | |
| </g>; | |
| } | |
| function Projection({x,y,reverse,focus}:{x:number;y:number;reverse:boolean;focus:number}) { | |
| return <g opacity={.24+.76*focus} transform={`translate(${x} ${y})`} data-projection={reverse?'p2t':'t2p'}> | |
| <rect width="140" height="116" rx="9" fill="#fff" stroke="#8093a7"/> | |
| <text x="70" y="25" textAnchor="middle" className="ds-micro" fill="#5f7286">LINEAR PROJECTION</text> | |
| <text x="70" y="54" textAnchor="middle" className="ds-projection-name" fill={ink}>{reverse?'Wₚ→ₜ':'Wₜ→ₚ'}</text> | |
| <rect x="10" y="67" width="120" height="29" rx="4" fill="#eef3f7"/> | |
| <path d="M0 76 H140" stroke="#a8bacb" strokeOpacity=".5"/> | |
| <text x="70" y="139" textAnchor="middle" className="ds-small" fill="#66788b">{config.d_model} → {config.d_model}</text> | |
| </g>; | |
| } | |
| function StatePacket({x,y,color,opacity=1}:{x:number;y:number;color:string;opacity?:number}) { | |
| return <g transform={`translate(${x} ${y})`} opacity={opacity} data-kind="hidden-state">{Array.from({length:6},(_,i)=><rect key={i} x={(i%2)*7} y={Math.floor(i/2)*7} width="5" height="5" rx="1" fill={color} fillOpacity={.45+(i%3)*.25}/>)}</g>; | |
| } | |
| function Lane({p,reverse,overview,id}:{p:number;reverse:boolean;overview:number;id:string}) { | |
| const encoderX=reverse?600:52, decoderX=reverse?52:600; | |
| const y=reverse?mix(230,413,overview):mix(230,119,overview); | |
| const alpha=reverse?Math.max(phase(p,.515,.54),overview):Math.max(1-phase(p,.493,.515),overview); | |
| const encoded=phase(p,reverse?.568:.072,reverse?.612:.16); | |
| const projected=phase(p,reverse?.612:.18,reverse?.666:.30); | |
| const writing=windowAt(p,reverse?.68:.32,reverse?.825:.493); | |
| const encoding=reverse?windowAt(p,.515,.61):1-phase(p,.16,.185); | |
| const projecting=reverse?windowAt(p,.61,.677):windowAt(p,.18,.315); | |
| const share=sharingState(p); | |
| const emphasis=(protein:boolean)=>Math.max(.3,protein?1-share.textFocus*.7:1-share.proteinFocus*.7); | |
| const eFocus=Math.max(encoding,overview*emphasis(reverse)),dFocus=Math.max(writing,projecting*.55,overview*emphasis(!reverse)),wFocus=Math.max(projecting,overview*(1-Math.max(share.textFocus,share.proteinFocus)*.7)); | |
| const shared=(protein:boolean)=>protein?Math.max(share.proteinFocus,share.both*.65):Math.max(share.textFocus,share.both*.65); | |
| const direction=reverse?-1:1; | |
| const start=reverse?600:280, end=reverse?280:600; | |
| return <g opacity={alpha} data-lane={reverse?'p2t':'t2p'}> | |
| <g opacity={.25+.75*Math.max(projecting,writing,overview)}> | |
| <path d={`M${start} ${y+123} H${end}`} fill="none" stroke="#c9d6e2" strokeWidth="2"/> | |
| <path d={`M${start} ${y+123} H${end}`} fill="none" stroke={`url(#${id}-flow${reverse?'-reverse':''})`} strokeWidth="2.5" pathLength="1" strokeDasharray="1" strokeDashoffset={1-Math.max(projected,overview)} markerEnd={`url(#${id}-${reverse?'blue':'orange'}-arrow)`}/> | |
| </g> | |
| <Node x={encoderX} y={y} protein={reverse} decoder={false} focus={eFocus} sharing={shared(reverse)}/> | |
| <Node x={decoderX} y={y} protein={!reverse} decoder focus={dFocus} sharing={shared(!reverse)} context={projected*(1-overview)}/> | |
| <Projection x={370} y={y+47} reverse={reverse} focus={wFocus}/> | |
| <g opacity={(1-overview)*encoded}> | |
| <text x="440" y={y+4} textAnchor="middle" className="ds-micro" fill="#5c7085">HIDDEN STATES</text> | |
| <text x="440" y={y+22} textAnchor="middle" className="ds-small" fill="#748598">Illustrative vectors</text> | |
| {Array.from({length:7},(_,i)=>{ | |
| const travel=phase(p,(reverse?.612:.18)+i*.006,(reverse?.639:.255)+i*.006); | |
| const emerge=phase(p,(reverse?.575:.095)+i*.005,(reverse?.595:.14)+i*.005); | |
| const x=mix(start+direction*(12+i*9),end-direction*21,travel); | |
| return <StatePacket key={i} x={x-6} y={y+113} color={travel>.55?(reverse?blue:orange):(reverse?orange:blue)} opacity={emerge*(1-phase(travel,.88,1))}/>; | |
| })} | |
| {Array.from({length:5},(_,i)=><StatePacket key={i} x={reverse?294:566} y={y+75+i*20} color={reverse?blue:orange} opacity={projected*.45}/>)} | |
| </g> | |
| <g opacity={overview}> | |
| <text x={reverse?828:52} y={y-(reverse?15:25)} textAnchor={reverse?'end':'start'} className="ds-lane-label" fill={reverse?blue:orange}>{reverse?'02 PROTEIN → TEXT':'01 TEXT → PROTEIN'}</text> | |
| <text x="440" y={y+202} textAnchor="middle" className="ds-small" fill="#64788a">{reverse?'Supervise with reference text':'Supervise with reference protein'}</text> | |
| </g> | |
| </g>; | |
| } | |
| function Input({p,reverse,example}:{p:number;reverse:boolean;example:Example}) { | |
| const color=reverse?orange:blue; | |
| const alpha=reverse?windowAt(p,.537,.815):1-phase(p,.477,.506); | |
| const tokens=reverse?example.protein.slice(0,16).split(''):words(example.text).slice(0,9); | |
| let wordX=52; | |
| return <g opacity={alpha}> | |
| <text x="52" y="35" className="ds-micro" fill={color}>{reverse?'REFERENCE PROTEIN · INDEPENDENT INPUT':'REFERENCE FUNCTION · HSP20 FAMILY'}</text> | |
| <rect x="52" y="52" width="776" height="92" rx="10" fill={reverse?'#fff5ee':'#edf5fc'} stroke={color} strokeOpacity=".22"/> | |
| {reverse?<> | |
| <text x="72" y="90" className="ds-sequence" fill={orange}>{example.protein.slice(0,48)}</text> | |
| <text x="72" y="119" className="ds-small" fill="#986651">First 48 of {example.protein.length} reference residues · not the generated sequence</text> | |
| </>:wrap(example.text,79).map((line,i)=><text key={i} x="72" y={78+i*23} className="ds-input-text" fill={blue}>{line}</text>)} | |
| {tokens.map((word,i)=>{ | |
| const w=reverse?37:word.length*8+18; | |
| const x=reverse?52+i*48:wordX; wordX+=w+6; | |
| const t=phase(p,(reverse?.546:.025)+i*.003,(reverse?.582:.085)+i*.003); | |
| const fade=1-phase(t,.67,1); | |
| return <g key={i} opacity={fade} transform={`translate(${mix(x,reverse?686:145,t)} ${mix(172,307,t)-Math.sin(t*Math.PI)*16})`}> | |
| <rect width={w} height="32" rx="4" fill={color} fillOpacity=".11" stroke={color} strokeOpacity=".4"/> | |
| <text x={w/2} y="21" textAnchor="middle" className="ds-input-token" fill={color}>{word}</text> | |
| </g>; | |
| })} | |
| <g opacity={phase(p,reverse?.60:.128,reverse?.63:.16)}> | |
| <path d={`M${reverse?714:166} 157 V209`} stroke={color} strokeOpacity=".25" strokeDasharray="3 5"/> | |
| <text x={reverse?696:184} y="192" textAnchor={reverse?'end':'start'} className="ds-small" fill={color}>Encoded into contextual states</text> | |
| </g> | |
| </g>; | |
| } | |
| function Output({p,reverse,example}:{p:number;reverse:boolean;example:Example}) { | |
| const start=reverse?.694:.335, end=reverse?.792:.467; | |
| const alpha=phase(p,start-.015,start)*(1-phase(p,reverse?.823:.487,reverse?.85:.514)); | |
| const items=reverse?words(example.generatedText):example.generatedProtein.slice(0,residuePreviewCount).split(''); | |
| const color=reverse?blue:orange, origin=reverse?166:714; | |
| let x=68,row=0; | |
| return <g opacity={alpha} data-output={reverse?'text':'protein'}> | |
| <path d={`M${origin} 435 V456 Q${origin} 468 ${origin-14} 468 H66`} fill="none" stroke={color} strokeOpacity=".2"/> | |
| <circle cx={origin} cy="438" r="4" fill={color}/> | |
| <text x="52" y="486" className="ds-micro" fill={color}>RECORDED {reverse?'TEXT':'PROTEIN'} OUTPUT</text> | |
| {items.map((item,i)=>{ | |
| const width=reverse?item.length*9+22:26, height=reverse?40:28; | |
| if (reverse && x+width>813) {x=68;row++;} | |
| const tx=reverse?x:90+(i%24)*30,ty=reverse?508+row*53:508+Math.floor(i/24)*36; | |
| x+=width+9; | |
| const t=segment(p,start+i*(end-start)/items.length,start+(i+1.9)*(end-start)/items.length); | |
| const eased=1-(1-t)**3; | |
| const lift=Math.sin(t*Math.PI)*45; | |
| return <g key={i} data-letter={item} data-arrived={t>=1} opacity={phase(t,0,.18)} transform={`translate(${mix(origin-width/2,tx,eased)} ${mix(438,ty,eased)-lift}) scale(${mix(.6,1,eased)})`}> | |
| <rect y="3" width={width} height={height} rx={reverse?6:4} fill={color} fillOpacity=".1"/> | |
| <rect width={width} height={height} rx={reverse?6:4} fill={reverse?'#e7f2fc':'#fff0e5'} stroke={color} strokeOpacity=".6"/> | |
| <text x={width/2} y={reverse?27:20} textAnchor="middle" className={reverse?'ds-word':'ds-residue'} fill={color}>{item}</text> | |
| </g>; | |
| })} | |
| {!reverse&&[0,1,2].map(row=><text key={row} x="52" y={528+row*36} className="ds-output-index" fill="#a48d7f">{String(row*24+1).padStart(3,'0')}</text>)} | |
| <text x="52" y="648" className="ds-small" fill="#687b8b">{reverse?'Word excerpts · archived prediction · illustrative timing':`First ${items.length} of ${example.generatedProtein.length} generated residues · complete sequence below`}</text> | |
| </g>; | |
| } | |
| export function DualScene({progress:p,example}:{progress:number;example:Example}) { | |
| const id=useId().replace(/:/g,''); | |
| const overview=phase(p,.839,.894); | |
| const share=sharingState(p); | |
| return <svg className="dual-scene-svg" viewBox="0 0 880 680" role="img" aria-label={`Ouroboros architecture, ${p<.515?'text to protein':p<.835?'protein to text':'joint supervised learning'}`} data-frame={p.toFixed(6)}> | |
| <defs> | |
| <linearGradient id={`${id}-flow`}><stop stopColor={blue}/><stop offset="1" stopColor={orange}/></linearGradient> | |
| <linearGradient id={`${id}-flow-reverse`}><stop stopColor={blue}/><stop offset="1" stopColor={orange}/></linearGradient> | |
| {[['blue',blue],['orange',orange]].map(([name,color])=><marker key={name} id={`${id}-${name}-arrow`} viewBox="0 0 8 8" refX="7" refY="4" markerWidth="5" markerHeight="5" orient="auto-start-reverse"><path d="M0 0 L8 4 L0 8" fill="none" stroke={color}/></marker>)} | |
| </defs> | |
| <g opacity={overview}> | |
| <text x="52" y="36" className="ds-micro" fill="#596e82">ONE PAIRED EXAMPLE · TWO TEACHER-FORCED TRAINING TASKS</text> | |
| <text x="828" y="36" textAnchor="end" className="ds-small" fill="#7b8995">large-v5</text> | |
| </g> | |
| <Input p={p} reverse={false} example={example}/> | |
| <Input p={p} reverse example={example}/> | |
| <Lane p={p} reverse={false} overview={overview} id={id}/> | |
| <Lane p={p} reverse overview={overview} id={id}/> | |
| <Output p={p} reverse={false} example={example}/> | |
| <Output p={p} reverse example={example}/> | |
| <g opacity={phase(p,.895,.908)} data-sharing="within-modality"> | |
| {[false,true].map(protein=>{ | |
| const color=protein?orange:blue,edge=protein?849:31,x=protein?828:52; | |
| const progress=protein?share.protein:share.text,focus=protein?share.proteinFocus:share.textFocus; | |
| return <g key={String(protein)} data-sharing-modality={protein?'protein':'text'} data-emphasis={focus.toFixed(4)} opacity={.2+.8*Math.max(progress,share.both)}> | |
| <path d={`M${x} 207 H${edge} V501 H${x}`} fill="none" stroke={color} strokeOpacity=".18" strokeWidth="2"/> | |
| <path d={`M${x} 207 H${edge} V501 H${x}`} fill="none" stroke={color} strokeWidth={1.5+focus*1.5} pathLength="1" strokeDasharray="1" strokeDashoffset={1-progress}/> | |
| {[207,501].map(y=><g key={y}><circle cx={x} cy={y} r={3+focus*3} fill="#f8fafc" stroke={color} strokeWidth="2"/><circle cx={x} cy={y} r={6+focus*6} fill="none" stroke={color} strokeOpacity={focus*.3}/></g>)} | |
| <rect x={protein?600:43} y="336" width="234" height="44" rx="8" fill={protein?'#fff0e7':'#e8f2fc'} stroke={color} strokeOpacity={focus}/> | |
| <text x={protein?717:160} y="354" textAnchor="middle" className="ds-small" fill={color}>Same {protein?'protein':'text'} self-attention weights</text> | |
| <text x={protein?717:160} y="371" textAnchor="middle" className="ds-shared-tag" fill={color}>ENCODER ↔ DECODER · BLOCKS 1–24</text> | |
| </g>; | |
| })} | |
| <text x="440" y="651" textAnchor="middle" className="ds-objective" fill={ink}>L = ½ L(text → protein) + ½ L(protein → text)</text> | |
| </g> | |
| </svg>; | |
| } | |