Lulucat

Ako Kimi K3 samo vytvoril digitálny ťah plniaceho pera

Gaoge ZhangGaoge Zhang

Chceli sme smerové plniace pero z Freeformu v Lulucat Notes. Špecifikáciou bola snímka obrazovky s rukopisom. Po dvoch modeloch, jednej rozlišujúcej otázke a eliptickom hrote vodové pero píše tak, ako má. Výskum, kód a validáciu vykonal Kimi K3 na Fireworks.

Aktualizované

Ručne písaná anglická kurzíva so slovami "fountain pen" nad riadkom čínskej kaligrafie, nakreslená plniacim perom s eliptickým hrotom na krémovom papieri: hrubá na zvislých ťahoch, tenká na vodorovných.

Vykreslené v pipeline Metal v Lulucat Notes, o ktorom je tento príspevok.

Lulucat Notes má obyčajné pero a zvýrazňovač. Ďalším nástrojom v pláne bolo vodové pero — smerové plniace pero, ktoré poznáte z Apple Notes a Freeformu, kde zvislé ťahy vychádzajú hrubé a vodorovné tenké. Špecifikáciou tohto nástroja nebol dokument. Bola to snímka obrazovky: tri riadky rukopisu, slová “pencilkit”, “无边记” a “这种有方向的水笔能力” — táto smerová schopnosť vodového pera.

Rovnako ako pri predchádzajúcom Metal pipeline, prácu vykonal Kimi K3, otvorený model spoločnosti Moonshot bežiaci na Fireworks: meranie, modelovanie, kód a validáciu. Človek dodal snímku obrazovky, odpovedal na jednu otázku a posúdil pocit na skutočnom iPade.

Špecifikácia je snímka obrazovky

Statický obrázok vám nepovie, prečo je ťah tenký. Môže ukázať iba to, aký je tenký a kde. Prvým krokom preto bolo meranie. Snímku obrazovky sme skenovali riadok po riadku a stĺpec po stĺpci, sledovali sme posun stredovej čiary každého ťahu, aby sme získali jeho smer, a potom sme šírku skenu prepočítali na skutočnú šírku pomocou sínusu daného uhla:

ŤahSmerSkutočná šírka
Vzostupný ťah písmena “l”, “pencilkit”≈ 78°27.3 px
Kmeň písmena “k”, “pencilkit”≈ 90°28 px
Ľavý klesajúci ťah v 力≈ 66°25.7 px
Spojenia kurzívy≈ 8°11 px
Čínske vodorovné ťahy (横)≈ 0°6–11 px

Pomer hrubého k tenkému je ≈ 2.5. Prispôsobenie bodu 66° dáva — v je takmer lineárne a maximum má na zvislej osi. V podstate ide o kurzívny hrot: vodorovná štrbina, ktorú vodorovné písmo nikdy neotvorí.

Verzia jedna: šírka zo smeru

Prvý model bol očividný. Pre každý vstupný bod vypočítaj smer, pomocou prispôsobenej krivky ho premapuj na šírku a pri zachytení zabuduj výsledok do polomeru bodu. Smer sa odhadoval kauzálne — ako exponenciálne klesajúci vážený priemer z niekoľkých posledných bodov oblúka, vypočítaný v priestore dvojnásobného uhla, aby obrátenie pohybu odhad nezrušilo. Používajú sa iba predchádzajúce body, takže živý ťah a potvrdený ťah sa zhodujú bajt po bajte.

Builder prešiel unit checkom: syntetické vodorovné, zvislé, 45° a obrátené dráhy všetky zabudovali teoretické šírky — 0.99, 2.52, 2.00 a 0.99 bodu. Renderovanie nepotrebovalo vôbec žiadny nový kód: ťah so zabudovaným polomerom je jednoducho reťaz okrúhlych pečiatok a náš point-sprite pipeline ich už kreslil.

Na iPade ho človek odmietol približne za desať sekúnd: „toto je umelecké pero, nie vodové pero“.

Dva príbehy sa zmestia do jedného obrázka

Prečo pôsobil nesprávne? Existovali dve možné vysvetlenia a snímka obrazovky ich nedokázala rozlíšiť:

  • Fixácia smeru. Geometria hrotu núti vodorovné ťahy zostať tenké a zvislé hrubé bez ohľadu na to, čo robí ruka. Presne to implementovala verzia jedna.
  • Tlak a rýchlosť. Pero je riadené tlakom a vzor na ukážke je iba dynamika rukopisu: pri klesajúcich ťahoch sa prirodzene tlačí silnejšie, spojenia sú prirodzene rýchle a ľahké.

Obe vysvetlenia vytvoria snímku s tenkými vodorovnými a hrubými zvislými ťahmi. Rozdiel sa ukáže, keď silno zatlačíte na vodorovný ťah. Verzia jedna ho ponechá tenký. Pero reagujúce na tlak ho zahustí. Preto sme človeku položili jednu otázku: má sa silno stlačený vodorovný ťah zhrubnúť?

„Nie. Vodorovné ťahy zostávajú tenké.“

Fixácia smeru bola potvrdená. Niečo však stále nesedelo, pretože verzia jedna bola tiež fixovaná na smer.

Odpoveď bola na koncoch ťahov

Ďalšia stopa bola na vrchole vzostupných ťahov. Priblíženie kmeňov písmen “l” a “k” na ukážke ukázalo dve veci: rovný ťah si od začiatku do konca zachováva jednu šírku a konce ťahov sú ploché diagonálne rezy — tvar dlátového hrotu, ktorý sa odliepa od papiera. Nie okrúhle bodky. Nie zúženia spôsobené tlakom.

Detailný výrez dvoch ručne písaných vzostupných ťahov z ukážky, z ktorých každý sa hore končí plochým diagonálnym rezom a po celej dĺžke má rovnomernú hrúbku.

To bolo skutočným významom „pocitu umeleckého pera“. Verzia jedna modelovala vzhľad ukážky — šírku ako funkciu odhadovaného smeru — ale nie pero. Odhadovač smeru je senzor: pri zašumenom vstupe kmitá, v zákrutách zaostáva a každý koniec ťahu zaokrúhli na kruh. Skutočný hrot nemá žiadny z týchto problémov, pretože nič nevypočítava. Šírka je geometria.

Verzia dva: eliptický hrot

Konečný model nemá vôbec žiadny odhadovač smeru. Hrot je orientovaná elipsa: dlhá os je vodorovná, krátka os je pevná. Pečiatky tejto elipsy sa husto ukladajú pozdĺž dráhy ťahu a všetko ostatné vyplýva z geometrie:

  • Vodorovný ťah ide pozdĺž otvoreného okraja, takže vždy vyjde široký — konštantná tenká čiara pri akomkoľvek tlaku. Presne podľa potvrdenej špecifikácie.

  • Zvislý ťah prechádza celou dlhou osou: , hrubý koniec.

  • Diagonálny ťah preberá šírku tetivy elipsy kolmej na smer pohybu,

  • Konce ťahov sú eliptické rezy — ploché konce v tvare hrotu z ukážky, bez ďalšej práce.

  • Tlak škáluje iba dlhú os, , takže pridáva objem atramentu pri klesajúcich ťahoch a nikdy nedokáže zhrubnúť vodorovný ťah.

Z meraní ukážky sme ponechali pt a pt, teda rovnaký pomer 2.5. Pečiatky sú pozdĺž oblúka od seba vzdialené 0.5 bodu; pri krátkom polomere 0.55 bodu vychádza najhoršie zvlnenie okraja približne na desatinu pixela.

Renderovanie si vyžiadalo jeden nový fragment shader a nič iné. Vertexový formát — pozícia, priemer, farba — už obsahoval všetko: priemer je dlhá os a krátka os je uniform pre každý priechod. Shader vyhodnocuje SDF elipsy s rovnakou rampou pokrytia polovice pixela ako naše okrúhle pečiatky, takže zostáva porovnateľný po pixeloch s referenčnou implementáciou Core Graphics (fillEllipse per stamp). Validácia prešla obvyklou bránou: syntetický korpus s dvoma ťahmi plniaceho pera, vyrenderovaný oboma spôsobmi a porovnaný pixel po pixeli — nulové štrukturálne rozdiely, pričom bodovo skontrolovaný vodorovný ťah meral 12 px v oboch rendereroch.

Dve vykreslenia toho istého ručne písaného slova "fountain" vedľa seba: vľavo okrúhle pečiatky s priemerom škálovaným podľa smeru a zaoblenými koncami, vpravo eliptické pečiatky s plochými koncami odrezanými hrotom a stabilnejšou šírkou.

Verzia jedna je vľavo, verzia dva vpravo. Rovnaký ručný vstup, rovnaký pipeline. Konce hovoria za všetko.

Na iPade nové pero prešlo okamžite: „好,很好“ — dobre. Veľmi dobre.

Nechať si nepodarok

Verzia jedna neskončila v koši. Je to zaujímavý štetec — len to nie je vodové pero. Preto bola vydaná ako prvá položka v novom menu experimentálnych štetcov pod názvom, ktorý jej dal človek: 漏水的圆珠笔, pretekajúce guľôčkové pero. Panel nástrojov dostal tlačidlo banky, ktoré otvorí textový zoznam experimentov; pridanie ďalšieho stojí jeden riadok v registri. Odmietnutý model nie je premárnená práca, ak môže byť vydaný ako jasne označený experiment.

Jeden večer cyklu

Celý priebeh — zmerať, namodelovať, zostaviť, otestovať na zariadení, položiť otázku, prerobiť model, prestavať, overiť — trval jeden večer. Kimi K3 na Fireworks viedol celú technickú stránku cyklu: navrhol meracie skeny, navrhol rozlišujúcu otázku namiesto druhého hádania, vymazal vlastný odhadovač smeru, keď dôkazy ukázali opak, a rozšíril pixel-diff harness ešte predtým, než sa dotkol aplikácie. Rýchlosť inferencie Fireworks udržala cyklus interaktívny — dlhé diffy v Metal a Swifte, skripty na analýzu pixelov a nástroje pre korpus prichádzali dosť rýchlo na to, aby úzkym miestom zostal človek a jeho úsudok.

Vzorec spolupráce bol rovnaký ako v článku o Metal pipeline a opäť fungoval: model je rýchly a presný; človek zodpovedá za vkus a overenie od začiatku do konca. Jedna veta spätnej väzby založenej na pocite — „umelecké pero, nie vodové pero“ — stačila na to, aby model našiel presnú chybu v modelovaní a nahradil ju jednoduchším návrhom.

Správny model sa ukázal byť menší než nesprávny. Verzia dva priniesla menej pohyblivých častí než verzia jedna — bez odhadovača, bez okna vyhladzovania a bez prispôsobeného exponentu. Hrot šírku nevypočítava. Hrot je šírka.