sobota 8. listopadu 2025

Jak jsem psal článek s jazykovým modelem

Tedy, nepsal jsem článek do impaktovaného časopisu. Skutečnou vědu jsem už dávno opustil a tento problém se nekvalifikuje, protože už jej vyřešili jiní. Ale nebyl lehký a už pěkných pár let mi ležel v hlavě. (Link zde).


Otázka je následující: Kdybych měl raketu, u které dokážu měnit rychlost, jakou palivo tryskou opouští komoru, můžu fungovat ve dvou módech: Při vysoké rychlosti (a tedy energii) spalin pálím palivo úsporně. Zrychlení je miniaturní, ale palivo mi dlouho vydrží a celkově můžu změnit rychlost rakety o hodně. Při nízké rychlosti spalin zvládnu posílat paliva za sekundu víc. Okamžité zrychlení je vyšší, ale palivo mi dřív dojde. Kdybych plánoval přesun mezi dvěma planetami, existuje určité optimum, jak to přesně dělat, abych do cíle dorazil co nejrychleji (a taky s cílem srovnal rychlost). A rychlost paliva se bude měnit v čase.

Teď nechci tolik psát o problému samotném, ale jak mi k řešení pomohla kombinace jazykových modelů (hlavně o3 a Gemini 2.5 Pro), a jak jsem s nimi vyřešil problém, který jsem sám vyřešit neuměl a poměrně rychle z něj dostal obstojně vypadající text. Z fyziky řeknu jenom tolik, aby bylo jasné, co se snažím vyřešit a kde mi modely pomohly.

Když jsem úlohu zkoušel řešit sám, uměl jsem si poradit s jednorozměrným případem bez gravitačního pole. Tam je to v podstatě variační úloha, která se musí vhodně parametrizovat, vyřešit Euler-Lagrangeovu rovnici a u řešení pak nastavit integrační konstanty tak, že člověk "sešije" etapu, kdy raketa zrychluje, kdy vypne motory a jen volně pluje, a kdy zpomaluje, do jedné rovnice. Varianta ve více rozměrech a s gravitačním polem hvězdy byla beznadějně složitá, a tak jsem zkoušel různé numerické procedury. 

Při cestě z planety na planetu je těžké se trefit do koncové polohy a rychlosti a člověk tedy neřeší jenom problém, aby trajektorie byla co nejrychlejší, ale aby v cíli vůbec skončil. Zkoušel jsem tedy opačný přístup: nakreslit trajektorii v čase tak, aby se do cíle trefila, spočítat, kolik mě to stálo paliva a pak minimalizovat palivo dokud není pod tolerovanou mezí, a pak teprv čas. Vůbec to nefungovalo. Trajektorie měla hodně parametrů a každý solver, který jsem zkusil se hned zasekával v lokálních minimech.Tak jsem dělal variace: nakreslit trajektorii, která se trefí do cíle a je definovaná jen několika málo parametry (první členy Fourierova rozvoje, spliny, apod.). To trochu fungovalo v tom smyslu, že to našlo nějaké trajektorie, ale ani zdaleka nebyly ty nejrychlejší, což se dalo poznat z různých kontrol konzistence.

A teď se dostávám ke své spolupráci s modely. Nejprve jsem se snažil ptát na různé variace této úlohy. Přesvědčit model, aby řešil nejprve tu jednoduchou jednorozměrnou úlohu, pak aby se zamyslel nad tou těžší, apod. Trvalo mi nějakou dobu se správně zeptat, ale pak mi o3 řekl o Pontriaginově principu maxima, který jsem neznal. Je to Hamiltonovská obdoba lagrangeových multiplikátorů pro variační úlohy, která explicitně zavádí extra proměnné pro to, jak raketu řídit. Přišlo mi to jako potenciálně nadějná cesta, a tak jsem trápil o3, aby rovnice vyřešil pro raketu v Keplerovském poli. Přesné řešení úloha nejspíš nemá, ale diferenciální rovnice model odvodil. Jedna z věcí, které je ale potřeba pořád kontrolovat je správnost. LLM dělají chyby. Řešení jsem střídavě předhazovat o3 s Gemini 2.5 Pro jako reviewerem, pak naopak, a pak zase znovu, až jsem se nakonec dostal k formulaci, které jsem docela věřil.

Další fáze byla implementace v Pythonu. Na podobné problémy existují specializované knihovny a stroj mi navrhoval kód s takovými knihovnami. Problém byl, že když kód nenašel řešení, vůbec jsem nevěděl proč. Přiměl jsem model napsat všechno od začátku. Chtělo to potom hodně debugování, kde člověk pochopí, co se děje špatně, řekne modelu, co zlepšit, a iteruje. Taky jsem používal modely střídavě, občas se jeden z nich zasekl a dělal pořád stejné chyby, a jiný model to rychle vyřešil. Vyplatilo se mi taky mít kód v gitu a umazávat nechtěné změny. Oba modely rády mění komentáře a stylistické věci, když kód přepisují. Pravděpodobně artefakt reinforcement-learningu, je velmi  patrné, které části kódu na výsledek nemají žádný vliv.  

Pak přišla část, kdy jsem kódu už docela věřil, ale pořád nenacházel řešení. To byl moment, kdy jsem musel modely vést hodně za ruku a použít určitý "expertní vhled". Přiměl jsem je přepsat kód tak, aby solver používal bezrozměrné diferenciální rovnice. Pak se totiž dá čekat, že hledané parametry budou alespoň řádově podobné jedničce a nebudou v rozsazích mnoho řádů jinde. Taky jsem zjednodušil úlohu: už jsem nechtěl najít řešení, kde cílová planeta je na konkrétním místě, hledal jsem prostě jakékoliv řešení, kde cílová rychlost je tečná ke kruhové dráze a má tu správnou velikost. Nakonec jsem takové řešení našel.

Finální krok byl začít s tím řešením, které už funguje a vždy malinko posunout cílovou pozici planety směrem, kde jsem ji chtěl mít. Pak se dá předpokládat, že i vstupní parametry se změní jen o malinko, a solver dost blízké řešení najde. Tyto úpravy jsem dělal sám ručně.  

Poslední fází bylo sepsat článek. Tam jsem vždy jeden model požádal, aby rovnice, na kterých je zdrojový kód založen a o kterých jsme se bavili, sepsal jako LaTeX. Ten druhý model jsem pak požádal o review a o to, aby našel chyby a možné vylepšení. Takto jsem iteroval, dokud jsem neměl LaTeX kód, se kterým jsem byl spokojen. Jediné, co mne teď odrazuje od toho, abych se s článkem nějak víc chlubil je, že jsem jej vlastně nikdy nečetl v takovém detailu, abych jeho obsahu úplně věřil.

Můj závěr je, že s moderními LLM modely se dá velmi dobře fungovat jako hydra-tým. Člověk je důležitou součástí procesu, aby držel záměr, a taky je potřeba, aby pomohl modelu překlenout úseky, kde by se model zasekl. Ale zároveň mi model ukázal nové přístupy, které bych bez něj jen těžko hledal, a usnadnil mi práci natolik, že jsem byl schopný dát dohromady po večerech po práci, což by se bez takového usnadnění jinak zcela jistě nestalo.

Žádné komentáře: