Things that live here:

  1. Work log, where I note things I feel I'll have to Google later.
  2. Journal, very similar but about non-IT topics.
  3. Blog for rare longer-form posts (last one below).

Feel free to look at what you can find here and enjoy yourself.


~17% of my country is occupied by Russia, and horrible things are happening there. You can help stop this! If you can donate - I contribute to (and fully trust) Come Back Alive and Hospitallers, but there are also other ways to help.


Latest posts from the Work log

Day 2306 / Advanced Python features

* did you know __init__.py is optional nowadays?

* you can do relative imports with things like "from ..other import foo"

* since 3.13 there is a @deprecated decorator that does what you think it does

* the new generics syntax also works on methods/functions: "def method[T](...)" very cool

* you can type kwargs with typeddicts and unpack: "def fn(*kwargs: Unpack[MyKwargs])"

* dataclasses (and pydantic) support immutable objects with: "class MyModel(BaseModel, frozen=True)" or "@dataclass(frozen=True)"

* class attributes on dataclasses, etc. can be defined with "MY_STATIC: ClassVar[int] = 42" this also supports abstract base classes (ABC)

* TypeVar supports binding to enforce subtypes: "TypeVar['T', bound=X]", and also a default since 3.13: "TypeVar['T', bound=X, default=int]"

* @overload is especially useful for get() methods to express that the return can't be none if the default isn't None

* instead of Union[a, b] or Optional[a] you can write "a | b" or "a | None" nowadays

* with match you can use assert_never() to ensure exhaustive matching in a "case _:" block

* typing has reveal_type() which lets mypy print the type it thinks something is

* typing's "Self" allows you to more properly annotate class method return types

* the time package has functions for monotonic clocks and others not just time()

Day 2305

vscode and cursor IDE settings

Autosave and format

    "files.autoSave": "onFocusChange",
    "[python]": {
        "editor.formatOnSave": true,
        // "editor.defaultFormatter": "charliermarsh.ruff",
		"editor.defaultFormatter": "ms-python.black-formatter",
		// reformat everything w/ ruff
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit",
            "source.organizeImports": "explicit"
        },
    },

For fix all etc. w/ ruff:

Adding rulers

    "editor.rulers": [
        78, 88
    ]

Ignoring stuff in flake8 pylint black etc.

Ignoring files:

# type: ignore
# flake8: noqa
# pylint: skip-file

Day 2296 / Evaluating NLG

Papers

Approaches

Main goal: coherence with human judgement

Kinds

Reference-free

  • LLM-estimate the probability is a generated text
    • assumption being that better texts have better probability
    • downsides: unreliable / low human correspondence according to 1
  • Ask an LLM how coherent / grammatical / criterium_name the output is from 0 to 5
    • downsides: LLMs will often pick 3 but G-Eval works around that

Reference-based

  • BLEU/ROUGE and friends (n-gram based)
    • low correlation with human metrics
  • (semantic) Similarity between two texts based on embeddings (BERTScore/MoverScore)
  • GPTScore2: higher probability to texts better fitting the framing
  • FACTUAL CONSISTENCY of generated summaries: FactCC, QAGS4

Framings (for GPT/LLM-based metrics)

  • Form-filling (G-Eval)
  • Conditional generation (=probability): GPTScore

How to evaluate evaluations

Meta-evaluators

  • Meta-evaluators are a thing! (= datasets based on human ratings)
    • G-Eval1 uses
      • SummEval 5
      • TopicalChat6
      • QAGS4 evaluating factual consistency/hallucinations
    • Pasted image 20250415172817.png 1
  • Correlation with human metrics

Stats

  • Many papers use various statistical bits to compare them.
  • G-Eval (p. 6)
    • Spearman, Kendall-Tau correlations
    • Krippendorf’s Alpha

On a specific task

Task formulation

  • Input:
    • Advert for a car.

      Car has 4 wheels

    • Target profile of possible client

      family with 10 kids 5 dogs living in the Australian bush

  • Output:
    • Advert targeted for that profile:

      ROBUST car with 4 EXTRA LARGE WHEELS made of AUSTRALIAN METAL able to hold 12 KIDS and AT LEAST 8 DOGS

Concrete approaches

  • Factual correctness / hallucinations
    • Framed as summarization evaluation: FactCC, QAGS4
  • GPTScore, G-Eval based on yet-to-be-determined-criteria
    • Coherence, consistency, fluency, engagement, etc. — the criteria used by meta-evaluators?
    • GPTScore aspects
    • TODO: ask the car company what do they care about except factual correctness and grammar
  • information density-ish? Use an LLM to get key-value pairs of the main info in the advert (number_of_wheels: 4), formulate questions based on each, and score better the adverts that contain answers to more questions!
    • Inspired by QAGS

TODO

  • LLM-as-a-judge and comparative assestment
  • think about human eval + meta-eval
  • think about what we want from the car company
    • metrics they care about

  1. G-Eval: <_(@liuGEvalNLGEvaluation2023) “G-Eval: NLG Evaluation using GPT-4 with Better Human Alignment” (2023) / Yang Liu, Dan Iter, Yichong Xu, Shuohang Wang, Ruochen Xu, Chenguang Zhu: z / http://arxiv.org/abs/2303.16634 / 10.48550/arXiv.2303.16634 _> ↩︎ ↩︎ ↩︎ ↩︎

  2. <_(@fuGPTScoreEvaluateYou2023) “GPTScore: Evaluate as You Desire” (2023) / Jinlan Fu, See-Kiong Ng, Zhengbao Jiang, Pengfei Liu: z / http://arxiv.org/abs/2302.04166 / 10.48550/arXiv.2302.04166 _> ↩︎ ↩︎

  3. <_(@zhongUnifiedMultiDimensionalEvaluator2022) “Towards a Unified Multi-Dimensional Evaluator for Text Generation” (2022) / Ming Zhong, Yang Liu, Da Yin, Yuning Mao, Yizhu Jiao, Pengfei Liu, Chenguang Zhu, Heng Ji, Jiawei Han: z / http://arxiv.org/abs/2210.07197 / 10.48550/arXiv.2210.07197 _> ↩︎

  4. <_(@wangAskingAnsweringQuestions2020) “Asking and Answering Questions to Evaluate the Factual Consistency of Summaries” (2020) / Alex Wang, Kyunghyun Cho, Mike Lewis: z / http://arxiv.org/abs/2004.04228 / 10.48550/arXiv.2004.04228 _> ↩︎ ↩︎ ↩︎

  5. <_(@fabbriSummEvalReevaluatingSummarization2021) “SummEval: Re-evaluating Summarization Evaluation” (2021) / Alexander R. Fabbri, Wojciech Kryściński, Bryan McCann, Caiming Xiong, Richard Socher, Dragomir Radev: z / https://direct.mit.edu/tacl/article/doi/10.1162/tacl_a_00373/100686/SummEval-Re-evaluating-Summarization-Evaluation / 10.1162/tacl_a_00373 _> ↩︎

  6. <_(@gopalakrishnanTopicalChatKnowledgeGroundedOpenDomain2023) “Topical-Chat: Towards Knowledge-Grounded Open-Domain Conversations” (2023) / Karthik Gopalakrishnan, Behnam Hedayatnia, Qinlang Chen, Anna Gottardi, Sanjeev Kwatra, Anu Venkatesh, Raefer Gabriel, Dilek Hakkani-Tur: z / http://arxiv.org/abs/2308.11995 / 10.48550/arXiv.2308.11995 _> ↩︎

Day 2295 / Latex referencing figure without caption

Tried to use subfig for two figures side by side, but couldn’t \autoref it.
I had a caption for the individual subfigs but not for the large figure itself. As soon as I added the caption it worked.

  \begin{figure}%
    \centering
    \subfloat[\centering caption subfig 1]{{\includegraphics[width=0.4\linewidth]{images/fig2.png}}}%
    \qquad
    \subfloat[\centering caption subfig 2]{{\includegraphics[width=0.4\linewidth]{images/fig4.png} }}%
    \caption{Without }
    \label{fig:twosamples}%
\end{figure}

\autoref{fig:twosamples}

Day 2270

Pydantic validation blues

Pydantic’s FilePath is like Path except that the file has to exist and be a file.

BUT FilePath when validating expects a string as input, not a Path! (in other words: FilePath(Path) doesn’t seem to work)

So when I create a Validator that converts str into Path 1:

@field_validator("filename", mode="before") 
@classmethod 
def parse_filename(cls, value: str | Path) -> Path: 
	return Path(value)

I get a wonderful

>       doc = UCFDocument.model_validate_json(json_string)
E       pydantic_core._pydantic_core.ValidationError: 1 validation error for UCFDocument
E       filename
E         Input is not a valid path for <class 'pathlib.Path'> [type=path_type, input_value=PosixPath('/home/sh/w/cor...n/doc.pdf_data/doc.pdf'), input_type=PosixPath]

tests/ucf/test_data_structures.py:179: ValidationError

Again, the error is a PosixPath not being a Path, though it is one:

E         Input is not a valid path for <class 'pathlib.Path'> [type=path_type, input_value=PosixPath('/home/sh/w/cor...n/doc.pdf_data/doc.pdf'), input_type=PosixPath]

# explicitly expecting a PosixPath creates an even better
E         Input is not a valid path for <class 'pathlib.PosixPath'> [type=path_type, input_value=PosixPath('/home/sh/w/cor...n/doc.pdf_data/doc.pdf'), input_type=PosixPath]

Not intuitive at all.

Solution is to give FilePath strings and only strings, or drop FilePath to begin with.

├── pydantic v2.10.6
│   ├── annotated-types v0.7.0
│   ├── pydantic-core v2.27.2
│   │   └── typing-extensions v4.12.2

  1. (don’t ask why I needed this, this is a minimal reproducible example only) ↩︎

CVAT for image labeling

CVAT is a really neat labelling platform, online + free on-premise w/ Docker.
(Github: cvat-ai/cvat: Annotate better with CVAT, the industry-leading data engine for machine learning. Used and trusted by teams at any scale, for data of any scale.)

I like it more than label studio for images, has more functions, but is also “heavier” / bulkier.

Love how it supports even 600mb 4-channel TIFF satellite images and is quite fast at that.

Bits:

  • Enable auto-save every N minutes
  • <C-a> for snipping polygons to existing polygon ponits
  • “Backup project” to re-import later, “Export project” to get e.g. YOLO annotations

Day 2268 / Current LLM evaluation landscape

The Open LLM Leaderboard is dead1, as good time as any to look for new eval stuff!

Day 2264

Installing SSDs into M.2 slots and drive stuff

CLI: sudo lshw -C disk tells you all disks h

Exporting gitea projects

Backup and Restore | Gitea Documentation has the full detailed story.

The easy stupid way for backing up gitea running in docker, untested and allegedly will fail if DB was being used during dumping.

docker exec -it --user git gitea-container bash

gitea dump

# then outside the container, copy from the gitea container to host OSooj

docker cp gitea-container:/whatveer/gitea-dump.zip /tmp

Importing: the docs don’t have the correct paths, not easy to follow.

EDIT: if your docker has /data mounted somewhere local, just copying that directory somewhere might work.

Day 2262 / Python fsspec copying files

In fsspec fs.copy() doesn’t really work from local to remote, also existing or not-existing directories etc.

Their documentation has a whole page on this: Copying files and directories — fsspec 2024.10.0.post13+gdbed2ec.d20241115 documentation

Day 2251 / Gitlab cli runner `glab`

GitLab CLI - glab | GitLab Docs: CLI thingy to interact with gitlab.

It’s really neat and has a cool CLI interface, either you set things through flags or you get a neat menu to choose from!

Smart enough to parse current directory!

Pipelines:

  • glab ci status for a curses interface
  • glab ci status -l is a live view as they run

Day 2250

Rotating PDF files

Because every single goddamn time

Command line: How do you rotate a PDF file 90 degrees? - Unix & Linux Stack Exchange

pdftk input.pdf cat 1-endwest output output.pdf

1- is needed because page range, here for all pages.

endwest etc from man page:

 [<begin page number>[-<end page number>[<qualifier>]]][<page rotation>]

The qualifier can be even or odd, and the page rotation can be north, south, east, west, left, right, or down.
Each option sets the page rotation as follows (in degrees): north: 0, east: 90, south: 180, west: 270, left: -90, right: +90, down: +180. left, right, and down make relative adjustments to a page’s rotation.

Python dynamic versioning with uv and hatch

[project] 
dynamic = ["version"] 

[tool.hatch.version] 
path = "..."

Path is a python file w/ version info. If using src layout, src has to be included in the path.j

For uv, this works. Described for example here: Versioning Python Projects with Hatch (I like __init__.py though, not about as that guide does)

uv-dynamic-versioning · PyPI exists but I don’t really see why.

git tags

Git Tag: A Tutorial for Tagging Releases in Git - DEV Community

#ligthweight tag
git tag v1.0.0

# full
git tag -a v1.0.0 -m "Releasing version v1.0.0"

Tags don’t get pushed automatically. For this, git push origin v1.0.0


Latest post from Blog

'The Hacker Manifesto', переклад українською

Оригінал: .:: Phrack Magazine ::.
Контекст: Маніфест хакера — Вікіпедія / Hacker Manifesto - Wikipedia
Існуючий дуже класний переклад, не відкривав, поки не закінчив свій: Маніфест хакера | Hacker’s Manifesto | webKnjaZ: be a LifeHacker

                               ==Phrack Inc.==

                    Том I, випуск 7, Ph-айл[0] 3 з 10

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Наступне було написано невдовзі після мого арешту...

	                        \/\Совість хакера/\/

	                               автор:

	                          +++The Mentor+++

	                           8 січня 1986р.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

	Сьогодні ще одного спіймали, пишуть у всіх газетах. "Кібер-скандал:
підлітку повідомили про підозру", "Кіберзлочинця затримали після
проникнення в систему банку".
	Тупа школота[1], вони всі однакові.

	Та чи ви, з вашою трафаретною ментальністю[2] та знаннями 
інформатики зразка першої половини пʼятидесятих[3], коли-небудь дивилися 
в душу хакера?[4] Чи вас колись цікавило, що є причиною його поведінки[5], 
які сили на нього впливали, що його сформувало?
	Я хакер, ласкаво прошу у мій світ...
	Мій світ почався ще зі школи... Я розумніший за більшість інших
дітей, і дурниці, які нам викладають, мені набридають.
	Тупий відстаючий[6], вони всі однакові.

	Восьмий, девʼятий, десятий, одинадцятий клас[7]. В пʼятнадцятий
раз слухаю, як вчителька пояснює, як скорочувати дроби. Мені все ясно. "Ні, 
Вікторія Миколаївна[8], я не написав проміжні кроки, я розвʼязав все усно..."
	Тупий підліток. Мабуть списав. Всі вони такі.

	Сьогодні я зробив відкриття. Я знайшов компʼютер. Ха, почекай-но,
це круто. Він робить те, що я від нього хочу. І якщо він помиляється,
це тому, що помилився я. А не тому що він мене не любить...
                         Або відчуває від мене загрозу...
                         Або думає що я тіпа самий умний[9]...
                         Або не любить викладати[10] і йому тут не місце...
	Тупий підліток. Він постійно тільки грає в свої ігри. Всі вони такі...

	Потім це відбулось... відчинились двері в світ... несучись телефонною 
лінією як героїн венами наркомана, надсилається електронний пульс,
шукається спасіння від невігластва навколо...[11] Знаходиться борд.[12]
	"Це воно... це те, до чого я належу..."
	Я з усіма тут знайомий... попри те, що я з ними ніколи не 
зустрічався, не розмовляв, і колись можливо більше нічого не чутиму про 
них... Я їх всіх знаю...
	Тупий підліток. Знову займає телефонну лінію... Вони всі однакові.

	Та можете не сумніватись,[13] що ми всі однакові... Нас годували
дитячими сумішами з ложки, коли ми хотіли стейк... а ті куски мʼяса, які 
до нас все ж потрапляли, були вже пережовані і без смаку. Над нами
панували садисти, або нас ігнорували байдужі. Для тих, хто хотіли чомусь 
нас навчити, ми були вдячними учнями, але їх було як краплин дощу в
пустелі.

	Цей світ зараз наш... світ електрона і комутатора, світ краси
бода[14]. Ми користуємося існуючою послугою не платячи за те, що могло б 
бути дуже дешевим, якби ним не завідували ненажерливі бариги[15], і ви 
називаєте нас злочинцями. Ми досліджуємо... і ви називаєте нас 
злочинцями. Ми шукаємо знання... і ви називаєте нас злочинцями. Ми 
існуємо без кольору шкіри, без національності і без релігійної 
нетерпимості... і ви називаєте нас злочинцями. Ви будуєте атомні бомби, 
ви ведете війни, ви вбиваєте, обманюєте, і брешете нам, намагаючись 
заставити нас повірити, що ви це робите для нашого блага, і попри все - 
це ми тут злочинці.

	Так, я злочинець. Мій злочин - моя допитливість. Мій злочин - 
оцінювати людей по тому, що вони кажуть і думають, а не по тому, як 
вони виглядають. Мій злочин в тому, що я вас перехитрив, і ви мене 
ніколи не пробачите за це.

	Я хакер, і це мій маніфест. Можливо ви зупините мене як особу, але ви 
ніколи не зупините нас всіх... зрештою, ми всі однакові.
	

Замітки:

  1. Ph-айл: worst of both worlds between phile and файл
  2. Damn kids: тупі/кляті/грьобані діти/школота1/малолітки2? Дякую цьому твіту Букви, який дає мені моральне право використовувати слово “школота”, бо нічого інше не клеїлося (“Окаяні дітлахи!")
  3. three-piece-psychology: інтерпретую як невисоку оцінку розвитку внутрішнього світу. Тому: пересічним/шаблонним/банальним/трафаретним3/примітивним/нехитрим/безхитрим; psychology: ‘інтелект’ але не зовсім, мені подобається ‘ментальність’
  4. and 1950’s technobrain: Німецький переклад, який сподобався англіцизмами та дав ідею перекласти technobrain в значенні “знання про компʼютери”, а не слово в слово: Berühmte Manifeste 2 – openPunk
  5. хакер/гакер: Вікіпедія вважає обидва допустимими; сам Авраменко ссилаючись на ті самі правила українського правопису теж вважає обидва допустимими, але все ж любить “г” більше (Хакер чи гакер - експрес-урок - YouTube). А я не можу і не буду. Хакер. I will die on this hill.
  6. what makes him tick: TODO, нічого не подобається. Що його рухає/надихає, що у нього в середині, …
  7. underachiever: хай буде “відстаючий”. Хоча пригадую з ЗНО, що суфікси уч/юч обмежені у вживанні, правильніше ВІДСТАЛИЙ мені не подобається.
  8. junior high or high school: тут додаю драми замість дослівності, тому що все ближче до оригіналу, що я можу придумати, занадто канцеляристично: “я закінчую базову чи повну загальну середню освіту”..?
  9. Ms. Smith:
  10. I’m a smart ass
  11. doesn’t like teaching: оплакую невикористаний варіант від душі “ненавидить себе, дітей, і педагогіку”. Дуже оплакую.
  12. a refuge from the day-to-day incompetencies is sought
  13. a board is found: мається на увазі електронна дошка оголошень (BBS — Вікіпедія), дід форумів і прадід іміджбордів. Найцікавіше слово для перекладу. Якщо буде “борд” то збережеться драматизм оригіналу, але є шанси, що хтось спутає з іміджбордами. Коли вони були популярні, нормальні люди в Україні їх не називали ніяк, російською були варіанти “доска”, “бибиэска”4. “BBS” був би найпростішим виходом; “електронна дошка оголошень” знову ж таки канцеляризм. По контексту далі очевидно, що мова йде про якесь спілкування, тому хай буде “борд”, принесу в жертву однозначність і зрозумілість милозвучності.
  14. you bet your ass we’re all alike: як же складно підбирати такі речі. Умовні embeddings з ML тут були б в тему. “Дай мені щось на кшталт ‘авжеж’ тільки більш emphatical”. Попередня версія “Авжеж ми всі однакові!”
    1. You bet – phrases: базара нет, по любому, я вас умоляю
    2. Будьте певні5
    3. ЩЕ Б ПАК — СИНОНІМІЯ | Горох — українські словники
      1. Авжеж?6
  15. the beauty of the baud: Бод — Вікіпедія Нехай мій (і єдиний можливий) переклад буде всім настільки ж зрозумілим, наскільки мені був зрозумілий оригінал, коли я його читав вперше.
  16. profitteering gluttons

Hat tip to:

Random: