Kimi K3 ఒక డిజిటల్ ఫౌంటెన్ పెన్ స్ట్రోక్ను ఎలా నిర్మించింది
Lulucat Notes లో Freeform లాంటి దిశాత్మక ఫౌంటెన్ పెన్ స్ట్రోక్ను మేము కోరుకున్నాం. స్పెక్ ఒక చేతిరాత స్క్రీన్షాట్ మాత్రమే. రెండు మోడళ్లు, ఒక తేడా చూపించే ప్రశ్న, ఒక ఎలిప్స్ నిబ్ తర్వాత, నీటి పెన్ రాయాల్సిన విధంగానే రాస్తుంది. పరిశోధన, కోడ్, మరియు ధృవీకరణ Fireworks పై నడిచిన Kimi K3 చేసింది.

ఈ పోస్ట్లో చెప్పిన Lulucat Notes Metal పైప్లైన్ ద్వారా render చేయబడింది.
Lulucat Notes లో ఒక సాధారణ పెన్ మరియు ఒక highlighter ఉన్నాయి. రోడ్మ్యాప్లో తదుపరి సాధనం నీటి పెన్ — Apple Notes మరియు Freeform లో మీకు తెలిసిన దిశాత్మక ఫౌంటెన్ పెన్; ఇందులో నిలువు స్ట్రోక్లు మందంగా, అడ్డ స్ట్రోక్లు సన్నగా కనిపిస్తాయి. ఈ సాధనానికి స్పెక్ ఒక డాక్యుమెంట్ కాదు. అది ఒక స్క్రీన్షాట్: మూడు వరుసల చేతిరాత, “pencilkit”, “无边记”, “这种有方向的水笔能力” అనే పదాలు — ఈ దిశాత్మక నీటి-పెన్ సామర్థ్యం.
ముందున్న Metal పైప్లైన్లాగే, ఈ పనిని Fireworks పై నడిచే Moonshot యొక్క open model Kimi K3 చేసింది: కొలతలు, మోడలింగ్, కోడ్, మరియు ధృవీకరణ. మనిషి స్క్రీన్షాట్ ఇచ్చాడు, ఒక ప్రశ్నకు సమాధానం చెప్పాడు, నిజమైన iPad పై దాని feelను అంచనా వేశాడు.
స్పెక్ ఒక స్క్రీన్షాట్
ఒక స్థిర చిత్రం స్ట్రోక్ ఎందుకు సన్నగా ఉందో చెప్పలేడు. అది ఎంత సన్నగా ఉందో, ఎక్కడ ఉందో మాత్రమే చెప్పగలదు. కాబట్టి మొదటి అడుగు కొలత. మేము స్క్రీన్షాట్ను వరుసల వారీగా, నిలువు వరుసల వారీగా scan చేసి, ప్రతి స్ట్రోక్ యొక్క centerline driftను ట్రాక్ చేసి దాని దిశను పొందాము; తర్వాత ఆ కోణం యొక్క sine ఉపయోగించి scan widthను true widthగా మార్చాము:
| స్ట్రోక్ | దిశ | నిజమైన వెడల్పు |
|---|---|---|
| “l” యొక్క ascender, “pencilkit” | ≈ 78° | 27.3 px |
| “k” యొక్క stem, “pencilkit” | ≈ 90° | 28 px |
| 力 యొక్క ఎడమవైపు దిగే sweep | ≈ 66° | 25.7 px |
| కర్సివ్ కనెక్టర్లు | ≈ 8° | 11 px |
| చైనీస్ అడ్డ గీతలు (横) | ≈ 0° | 6–11 px |
మందం-నుండి-సన్నదనం నిష్పత్తి ≈ 2.5. 66° బిందువుకు
వెర్షన్ ఒకటి: దిశ నుంచి వెడల్పు
మొదటి మోడల్ సూటిగా కనిపించింది: ప్రతి input pointకు ఒక దిశను compute చేసి, fit చేసిన curve ద్వారా దిశను widthకు map చేసి, capture సమయంలో ఫలితాన్ని ఆ point యొక్క radiusలో bake చేయడం. దిశను causalగా అంచనా వేశారు — arcలోని చివరి కొన్ని pointలపై exponentially decaying weighted averageను తీసుకుని, ప్రయాణ దిశ తిరిగినప్పుడు అంచనా పరస్పరం రద్దు కాకుండా doubled-angle spaceలో compute చేశారు. గత pointలు మాత్రమే ఉపయోగించడంతో live stroke మరియు committed stroke byteకు byte ఒకటే.
Builder తన unit checkను పాస్ చేసింది: synthetic horizontal, vertical, 45°, మరియు reversal paths అన్నీ theoretical widthsను — 0.99, 2.52, 2.00, మరియు 0.99 points — bake చేశాయి. Renderingకు కొత్త code ఏదీ అవసరం లేదు: baked-radius stroke అంటే round stamps యొక్క గొలుసే, మా point-sprite pipeline వాటిని ఇప్పటికే గీస్తోంది.
iPad పై, మనిషి దాన్ని తిరస్కరించడానికి సుమారు పది సెకన్లు మాత్రమే తీసుకున్నాడు: “ఇది ఒక art pen, నీటి పెన్ కాదు.”
రెండు వివరణలు ఒకే చిత్రానికి సరిపోతాయి
అది ఎందుకు తప్పుగా అనిపించింది? రెండు సంభావ్య వివరణలు ఉన్నాయి, కానీ స్క్రీన్షాట్ వాటిని వేరు చేయలేకపోయింది:
- దిశా-లాక్. Nib geometry చేతి కదలిక ఎలా ఉన్నా అడ్డాలను సన్నగా, నిలువులను మందంగా చేస్తుంది. వెర్షన్ ఒకటి అమలు చేసింది ఇదే.
- ఒత్తిడి మరియు వేగం. పెన్ pressure-driven, నమూనాలోని pattern కేవలం చేతిరాత dynamics: downstrokeలు సహజంగా ఎక్కువ ఒత్తిడితో ఉంటాయి, connectors సహజంగా వేగంగా మరియు తేలికగా ఉంటాయి.
రెండూ సన్నని అడ్డాలు, మందమైన నిలువులతో ఒకే రకమైన స్క్రీన్షాట్ను సృష్టిస్తాయి. తేడా ఏమిటంటే, ఒక అడ్డ స్ట్రోక్పై బలంగా నొక్కినప్పుడు ఏమి జరుగుతుంది. వెర్షన్ ఒకటి దాన్ని సన్నగానే ఉంచుతుంది. Pressure pen దాన్ని మందంగా చేస్తుంది. అందుకే మనిషిని ఒక ప్రశ్న అడిగాము: బలంగా నొక్కిన అడ్డ స్ట్రోక్ మందంగా మారాలా?
“లేదు. అడ్డాలు సన్నగానే ఉంటాయి.”
దిశా-లాక్ నిర్ధారించబడింది. అయినా మరొక విషయం తప్పుగా ఉంది, ఎందుకంటే వెర్షన్ ఒకటి కూడా direction-locked గానే ఉంది.
సమాధానం స్ట్రోక్ చివర్లలో ఉంది
తదుపరి సూచన ascenderల పైభాగంలో కనిపించింది. నమూనాలోని “l” మరియు “k” stemలను zoom చేయగా రెండు విషయాలు కనిపించాయి: ఒక సూటి స్ట్రోక్ మొదటి నుంచి చివరి వరకు ఒకే widthను ఉంచుతుంది, మరియు స్ట్రోక్ చివర్లు flat diagonal cuts — chisel nib పైకి లేచినప్పుడు కనిపించే ఆకారం. అవి round dots కాదు. Pressure tapers కూడా కాదు.

మనిషి చెప్పిన “art pen feel” అంటే ఇదే. వెర్షన్ ఒకటి నమూనా యొక్క lookను — అంచనా వేసిన directionకు functionగా widthను — model చేసింది, కానీ penను కాదు. Direction estimator ఒక sensor: noisy inputపై jitter అవుతుంది, corners చుట్టూ lag అవుతుంది, ప్రతి స్ట్రోక్ చివరను circleగా round చేస్తుంది. నిజమైన nibకు ఈ సమస్యలు ఏవీ ఉండవు, ఎందుకంటే అది ఏదీ compute చేయదు. Width అనేది geometry.
వెర్షన్ రెండు: ఒక ellipse nib
చివరి మోడల్లో direction estimator అసలు లేదు. Nib ఒక oriented ellipse: long axis అడ్డంగా, short axis fixed. ఈ ellipse యొక్క stampsను స్ట్రోక్ path వెంట దట్టంగా ఉంచుతారు; మిగతాదంతా geometry నుంచి సహజంగానే వస్తుంది:
-
ఒక అడ్డ స్ట్రోక్ open edge వెంట ప్రయాణిస్తుంది, కాబట్టి అది ఎప్పుడూ
widthగా వస్తుంది — ఏ pressureలోనైనా మారని సన్నని గీత. నిర్ధారించిన spec ఇదే. -
ఒక నిలువు స్ట్రోక్ మొత్తం long axisను దాటుతుంది:
, మందమైన చివర. -
ఒక diagonal స్ట్రోక్ ప్రయాణ దిశకు లంబంగా ఉన్న ellipse యొక్క chord widthను తీసుకుంటుంది,
-
స్ట్రోక్ చివర్లు elliptical cuts — నమూనాలో కనిపించిన flat nib-shaped ends; అదనపు పని లేకుండానే వస్తాయి.
-
Pressure long axisను మాత్రమే scale చేస్తుంది,
, కాబట్టి downstrokeలపై ink volume పెరుగుతుంది, కానీ అడ్డ స్ట్రోక్ ఎప్పటికీ మందం కాదు.
నమూనా కొలతల ఆధారంగా
Renderingకు ఒక కొత్త fragment shader మాత్రమే అవసరమైంది. Vertex format — position, diameter, color — ఇప్పటికే అన్నింటినీ మోసుకెళ్తోంది: diameter long axis, short axis ప్రతి passకు ఒక uniform. Shader మా round stamps ఉపయోగించే అదే half-pixel coverage rampతో ellipse SDFను evaluate చేస్తుంది; అందువల్ల Core Graphics reference implementationతో (fillEllipse per stamp) pixel స్థాయిలో పోల్చవచ్చు. Validation సాధారణ gateలోనే జరిగింది: రెండు fountain strokes ఉన్న synthetic corpusను రెండు విధాలుగా render చేసి pixel by pixel పోల్చాము — structural differences శూన్యం; spot-check చేసిన ఒక horizontal stroke రెండు renderersలోనూ 12 pxగా కొలిచాం.

ఎడమవైపు వెర్షన్ ఒకటి, కుడివైపు వెర్షన్ రెండు. అదే handwritten input, అదే pipeline. చివర్లే కథను చెబుతాయి.
iPad పై కొత్త పెన్ వెంటనే పాస్ అయింది: “好,很好” — మంచిది. చాలా మంచిది.
ఈ తప్పును ఉంచుకోవడం
వెర్షన్ ఒకటి చెత్తబుట్టలోకి వెళ్లలేదు. అది నిజంగా ఆసక్తికరమైన brush; అది నీటి పెన్ కాదు, అంతే. కాబట్టి మనిషి పెట్టిన పేరు 漏水的圆珠笔, అంటే leaky ballpoint, కింద కొత్త experimental-brush menuలో మొదటి entryగా ship అయింది. Toolbarలో flask button వచ్చింది; అది experiments యొక్క text listను తెరుస్తుంది. తర్వాతిదాన్ని జోడించడానికి registryలో ఒక line చాలు. స్పష్టంగా లేబుల్ చేసిన experimentగా ship చేయగలిగితే rejected model వృథా పని కాదు.
ఒక సాయంత్రంలో loops
మొత్తం arc — measure, model, build, device, question, remodel, rebuild, validate — ఒక సాయంత్రం పట్టింది. Fireworks పై నడిచిన Kimi K3 loop యొక్క మొత్తం technical వైపును నిర్వహించింది: measurement scansను రూపొందించడం, రెండోసారి ఊహించడానికి బదులు discriminating questionను ప్రతిపాదించడం, evidence మారినప్పుడు తన direction estimatorను తొలగించడం, appను తాకే ముందు pixel-diff harnessను విస్తరించడం. Fireworks inference speed loopను interactiveగా ఉంచింది — పొడవైన Metal మరియు Swift diffs, pixel-analysis scripts, corpus tooling అన్నీ మానవ judgment మాత్రమే bottleneckగా మిగిలేంత వేగంగా వచ్చాయి.
Metal pipeline పోస్ట్లో మేము రాసిన collaboration pattern ఇదే, ఇది మళ్లీ పనిచేసింది: model వేగంగా మరియు ఖచ్చితంగా ఉంది; human taste మరియు end-to-end verificationను చూసుకున్నాడు. feel ఆధారంగా వచ్చిన ఒక feedback sentence — “art pen, నీటి పెన్ కాదు” — model సరైన modeling errorను గుర్తించి, దాని స్థానంలో సరళమైన designను పెట్టడానికి సరిపోయింది.
సరైన model తప్పు model కంటే చిన్నదిగా తేలింది. వెర్షన్ రెండు వెర్షన్ ఒకటి కంటే తక్కువ moving partsతో ship అయింది — estimator లేదు, smoothing window లేదు, fitted exponent లేదు. Nib widthను compute చేయదు. Nib అదే width.