Compare commits

...

59 Commits

Author SHA1 Message Date
Basyrov Rustam
eb4c3fce2d Merge branch 'dev'
All checks were successful
ci / deploy (push) Successful in 8m58s
2025-06-02 17:22:08 +03:00
Basyrov Rustam
a80e20862c add jenkins to CV 2025-06-02 17:22:05 +03:00
Basyrov Rustam
216cf27e1b Merge branch 'dev' 2025-06-02 17:16:32 +03:00
Basyrov Rustam
6bddd048ca remove test stuff 2025-06-02 17:14:34 +03:00
Basyrov Rustam
7f880df10c Merge branch 'dev' 2025-06-02 17:11:03 +03:00
Basyrov Rustam
fd3225b8b3 Test 2025-06-02 17:10:58 +03:00
Basyrov Rustam
32c1955305 Merge pull request #5 from rustbas/dev
fix "about me" page
2025-06-02 13:56:01 +03:00
Basyrov Rustam
eb295fdf41 fix "about me" page 2025-06-02 13:55:09 +03:00
Basyrov Rustam
4ebb210103 fix typo 2025-05-30 16:06:44 +03:00
Basyrov Rustam
3595549e62 add date 2025-05-30 16:03:24 +03:00
Basyrov Rustam
e61c314311 add some references 2025-05-30 16:03:21 +03:00
Basyrov Rustam
304c3cc1d4 remove some stuff 2025-05-30 15:48:31 +03:00
Basyrov Rustam
457a1d397b finish article type-pred 2025-05-30 15:44:35 +03:00
Basyrov Rustam
96910eea02 add signature calculating note 2025-05-30 15:29:09 +03:00
Basyrov Rustam
f180169558 new index to working ToC 2025-05-30 14:04:51 +03:00
Basyrov Rustam
8456b95098 some new settings
going to mkdocs-material
2025-05-30 14:03:11 +03:00
Basyrov Rustam
ac172c0357 add code block descriptions 2025-05-30 13:39:37 +03:00
Basyrov Rustam
d04ae45f10 some addings 2025-05-29 21:04:48 +03:00
Basyrov Rustam
9f012896d8 add link to Gauss's smoothing 2025-05-29 21:04:42 +03:00
Basyrov Rustam
80a547df3b add png's 2025-05-29 21:04:12 +03:00
Basyrov Rustam
8af5a68a39 neural network 2025-05-12 21:01:19 +03:00
Basyrov Rustam
b71d1d4809 new stage 2025-05-11 20:11:03 +03:00
rustam
424e72f232 two heads 2025-05-10 15:54:28 +03:00
Basyrov Rustam
709bb61cf3 Intro 2025-05-09 19:08:31 +03:00
Basyrov Rustam
7d93ef9790 references 2025-05-09 18:48:21 +03:00
Basyrov Rustam
1bfac10d9a pics? 2025-05-09 18:46:24 +03:00
Basyrov Rustam
48d07c7d65 headers 2025-05-06 17:27:21 +03:00
Basyrov Rustam
d21f1db4bf Merge branch 'main' into filetype_prediction 2025-05-05 22:33:27 +03:00
Basyrov Rustam
2ad1e0c48d fix typo in article name 2025-05-05 22:33:20 +03:00
Basyrov Rustam
b5d706683c init new article 2025-05-04 22:07:46 +03:00
Basyrov Rustam
344ee7a343 Merge pull request #4 from rustbas/dev
ACH
2025-04-23 19:13:48 +03:00
Basyrov Rustam
9a36e5d7d2 date 2025-04-23 19:12:05 +03:00
Basyrov Rustam
8ff36d994d some pretty/typos 2025-04-23 18:40:55 +03:00
Basyrov Rustam
ee294e1d37 typos 2025-04-23 17:04:28 +03:00
Basyrov Rustam
775c3e6936 finish ach article 2025-04-23 17:03:45 +03:00
Basyrov Rustam
7e995357f9 add *.bak to .gitignore 2025-04-23 16:39:09 +03:00
Basyrov Rustam
170f9555d2 fix typos (aspell) 2025-04-23 16:38:54 +03:00
Basyrov Rustam
6af8d049b9 some stuff 2025-04-23 16:36:36 +03:00
Basyrov Rustam
3ba1a5da15 some add 2025-04-21 22:22:22 +03:00
rustam
2eebeefdde ACH 2025-04-03 13:29:02 +03:00
Basyrov Rustam
aae89afff0 init page 2025-04-01 14:14:14 +03:00
Basyrov Rustam
4c78c1990f init new section 2025-04-01 14:14:04 +03:00
Basyrov Rustam
6bb96d67de init page 2025-04-01 13:33:28 +03:00
Basyrov Rustam
971107a38e fix typo 2025-01-28 17:48:27 +03:00
Basyrov Rustam
8a4d5e673a another fix 2025-01-24 14:18:25 +03:00
Basyrov Rustam
ffa3fc8b00 fix 2025-01-24 14:17:32 +03:00
Basyrov Rustam
0d95d51d55 fix date 2025-01-24 14:10:15 +03:00
Basyrov Rustam
df0bbb0f4b Merge branch 'dev' 2025-01-24 14:04:33 +03:00
Basyrov Rustam
72133bd71f fix typos 2025-01-24 14:04:11 +03:00
Basyrov Rustam
c0d7ce44c7 article 2025-01-24 11:15:29 +03:00
Basyrov Rustam
dba60d8a77 add distccmon-text picture 2025-01-24 11:15:25 +03:00
Basyrov Rustam
49fa395a10 init motivation 2025-01-23 22:01:31 +03:00
Rustam
8d50afe15b init article about vagrant and distcc 2025-01-12 12:08:31 +03:00
rustbas
719826c1a5 Merge pull request #3 from rustbas/dev
`stat-madness.md`
2024-11-16 08:06:46 +00:00
Basyrov Rustam
744f329f68 some fixes 2024-11-16 11:05:26 +03:00
Basyrov Rustam
d648934dd3 add pics 2024-11-16 10:13:54 +03:00
Basyrov Rustam
9c0dd24b78 init article
without pictures!
2024-11-13 19:28:07 +03:00
Basyrov Rustam
87c033da3a Merge branch 'dev'
Some checks failed
ci / deploy (push) Has been cancelled
2024-11-04 00:35:52 +03:00
Basyrov Rustam
e36e9f8bbb Init README.md 2024-11-04 00:35:43 +03:00
18 changed files with 924 additions and 16 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
venv/ venv/
*.bak

1
README.md Normal file
View File

@@ -0,0 +1 @@
# blog

217
docs/common/ach.md Normal file
View File

@@ -0,0 +1,217 @@
# Немного про принятие решений и нейросети
## Мотивация
Сейчас очень распространились нейросети различных форматов: для работы
с текстом, видео, аудио, для обработки и прогнозирования данных. В
твиттере ажиотаж вокруг новой возможности ChatGPT: обработка
изображений в стиле студии Ghibli, известной по фильмам "Мой сосед
Тоторо", "Унесенные призраками" и пр.
Нейросети применяются не только для "развлечений", но и в весьма
ответственных областях, например, анализ снимков рентгена, разработке
программ. Для последнего даже был придуман термин [Vibe Coding](https://en.wikipedia.org/wiki/Vibe_coding).
Я, в некоторой степени, являюсь луддитом по отношению к нейросетям,
которые генерируют тексты. Это обусловлено преимущественно тем, что
люди относятся к ним, как к некой "палочке-выручалочке", которая
представляет собой кнопку "сделать красиво". Такой подход не только
снижает *критичное отношение* к окружающему миру (зачем придумывать
решение, если нейросеть может сгенерировать его за меня, *даже если он
будет некорректный*), но уменьшает общее качество деятельности.
Но даже так, я не являюсь противником нейросетей *просто по
существу*. У всего есть качественные области применения, иногда не
совсем очевидные.
Здесь я хочу рассказать об **анализе конкурирующих гипотез**,
**мозговом штурме** и **попытке применения в них нейросетей**.
## Большие языковые модели
Должен признать, что у меня весьма смутное представление о работе
таких нейросетей *под капотом*.
В моем понимании, суть их работы заключается в том, при анализе
запроса любого толка, они "понимают", какие слова будут уместны в
контексте этого запроса (получается такая очень сложная "китайская
комната"[2]).
Результатом же работы нейросети является текст, который я воспринимаю
как *случайное число*, которое параметризовали запросом (*prompt*),
примерно как случайное число из нормального распределения
параметризуется математическим ожиданием и дисперсией. Хотя, есть и
[другое мнение](https://x.com/tsoding/status/1896205552415658463).
А если есть случайность, то значит можно её можно использовать.
## Суть анализа конкурирующих гипотез
**Анализ конкурирующих гипотез** - методология, разработанная Ричардом
Хоером в 70-х годах. Целью создания метода было уменьшение влияния
когнитивных сдвигов (*bias*) на работу аналитиков при анализе и принятии
решений.
Особенность метода заключается в том, что вместо сопоставления каждой
гипотезе всех доказательств, наоборот, каждое доказательство
противопоставляется всем гипотезам.
Пошаговая инструкция к методу:
1. Определить все **возможные** гипотезы. Лучше использовать *команду
аналитиков* с различным опытом, чтобы реализовать **мозговой
штурм**.
2. Создать список всех существенных доказательств, аргументов "за" и
"против, а также фактов, которые могут помочь в анализе гипотез.
3. Подготовить матрицу, где номер строки будет отвечать за номер
аргумента, а номер столбца за номер гипотезы.
4. Проверить матрицу: уточнить формулировку гипотез, удалить аргументы,
которые не имеют диагностической ценности.
5. Сопоставьте каждое доказательство каждой гипотезе. Двигайтесь
по столбцам.
6. Проанализируйте, как устойчивы ваши заключение к аргумента.
Посмотрите, как изменится вывод в случае, если какие-то аргументы
окажутся ложными.
7. Составьте отчет. Проверьте правдоподобность каждой гипотезы, *не
только самой приятной*.
8. Оцените дальнейшие шаги для улучшения оценки.
Можно долго вдаваться в детали реализации метода. В нашем случае, нас
интересует часть, где необходимо придумать как можно большее число
вариантов, используя **мозговой штурм**.
### Применение нейросетей
Когда нет большой *команды аналитиков*, можно попробовать заменить их
нейросетью. В данном случае, нейросеть можно применить в двух местах:
1. В п. 1 для определения всех **возможных** гипотез. Само собой,
качество этих гипотез определяет аналитик, но их генерацию можно
частично делегировать ИИ.
2. В п.2 можно попробовать определить области, где **искать
доказательства** за и против. Нужно помнить, что доказательства
также могут представлять собой *отсутствие* чего-либо.
## Пример
Приведу пример (полученный также с помощью ИИ): "Почему в городе
резко выросло число ДТП на конкретном перекрестке?".
Полученный список гипотез:
```
- Инфраструктурные факторы
1. **Изменение дорожной разметки или знаков**: Неправильно
нанесенная разметка, противоречивые знаки или их отсутствие.
2. **Неисправность светофора**: Сбои в работе (например, мигающий
желтый сигнал), некорректные временные интервалы.
3. **Сужение полос** из-за ремонтных работ, парковки или временных
ограждений.
4. **Новые препятствия**: Установка рекламных щитов, столбов,
деревьев, ограничивающих обзор.
5. **Плохое состояние дорожного покрытия**: Выбоины, ледяная
корка, отсутствие освещения в темное время суток.
6. **Изменение типа перекрестка**: Например, переход от светофора
к круговому движению без должного информирования.
- Транспортный поток
7. **Рост трафика** из-за открытия новых ТЦ, офисов, жилых
комплексов.
8. **Перенаправление движения** с других улиц из-за ремонта,
аварий или изменений в маршрутах.
9. **Увеличение грузового транспорта**: Новые логистические
маршруты через перекресток.
10. **Активность общественного транспорта**: Новые автобусные
остановки или троллейбусные линии.
- Человеческий фактор
11. **Нарушение ПДД водителями**: Частые проезды на красный свет,
превышение скорости, агрессивное вождение.
12. **Низкая видимость пешеходов**: Отсутствие зебры, освещения
или знаков у пешеходного перехода.
13. **Отвлекающие факторы**: Яркая реклама, использование
телефонов за рулем.
14. **Новички на дороге**: Увеличение числа неопытных водителей
(например, из-за новой автошколы поблизости).
- Внешние условия
15. **Погодные аномалии**: Гололед, туман, дождь, слепящее солнце
в определенные часы.
16. **Сезонные факторы**: Туристы, листопад, снежные заносы.
17. **Животные на дороге**: Бродячие собаки, птицы или дикие
животные, вызывающие резкие торможения.
- Технические причины
18. **Неисправности автомобилей**: Массовые отзывы авто из-за
брака тормозных систем.
19. **Сбои в системах помощи водителю**: Например, ошибки в
навигаторах, предлагающих опасные маневры.
20. **Электромагнитные помехи**, влияющие на работу датчиков или
светофоров.
- Организационные и социальные факторы
21. **Снижение контроля со стороны ГИБДД**: Уменьшение числа
патрулей или камер фиксации нарушений.
22. **Новые правила движения**, которые водители не успели
изучить.
23. **Вандализм**: Повреждение знаков, светофоров или разметки.
24. **Массовые мероприятия**: Концерты, митинги или фестивали,
создающие заторы и невнимательность.
- Статистические аномалии
25. **Случайная кластеризация**: Краткосрочный всплеск аварий без
системной причины.
26. **Изменение методики учета ДТП**: Теперь фиксируются даже
мелкие столкновения, которые раньше игнорировались.
27. **Ошибки в данных**: Технические сбои при сборе статистики.
```
Хочется обратить внимание, что гипотез очень много и часть из низ
можно отмести в зависимости от контекста исследования. Но эту задачу
**должен делать аналитик**.
Ответ на вопрос: "где искать доказательства":
```
- Данные ГИБДД: Статистика нарушений, протоколы ДТП, видео с камер.
- Дорожные службы: Отчеты о ремонтах, изменениях разметки, проверках
светофоров.
- Метеорологические службы: Погодные сводки на даты аварий.
- Соцсети и СМИ: Жалобы водителей, репортажи о проблемах на
перекрестке.
- Технические данные: Логи навигаторов (Яндекс.Пробки, Google Maps),
отчеты автопроизводителей.
```
На основе полученных ответов можно пробовать строить анализ.
## Выводы
В заключении этого небольшого текста, хочу отметить несколько выводов:
1. Данная заметка не является инструкцией в стиле "вы используете
языковые модели неправильно". Здесь я просто хочу высказать мнение
касательно ИИ и отметить, какое применение я вижу у этого
инструмента.
2. В моем понимании, нейросети подойдут в тех случаях, когда нужно
применить **мозговой штурм**: составление гипотез, поиск
доказательств, составление списка действия для решения задачи в
методологии *GTD*.
3. Не стоит отдавать под контроль ИИ принятие решений на _любом
уровне_. Все логические выкладки должен делать аналитик, который
использует языковую модель как инструмент.
4. Думаю, обращаться за помощью к нейросетям, нужно если не в
*последнюю очередь*, то хотя бы не сразу. Во-первых, стоит не
забывать про собственное *критичное отношение* к миру, а во-вторых,
цель **мозгового штурма** -- это сбор сех_ возможных вариантов,
которые могут пройти ниже радаров нейросети, и про которые потом не
станет думать аналитик, будучи отвлеченный анализом результатов.
По итогу, я убежден, что языковые модели -- это *инструмент*, который
можно применить во множестве областей, но это все же *инструмент*. Он
не решит все проблемы за вас, но поможет вам решить ваши проблемы.
## Источники
1. [Psychology of intelligence analysis](https://www.amazon.com/Psychology-Intelligence-Analysis-Richards-Heuer/dp/B0016OST3O)
2. [Китайская комната](https://ru.wikipedia.org/wiki/%D0%9A%D0%B8%D1%82%D0%B0%D0%B9%D1%81%D0%BA%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BD%D0%B0%D1%82%D0%B0)

3
docs/common/index.md Normal file
View File

@@ -0,0 +1,3 @@
# Общие заметки
## 2025-04-23 [Немного про принятие решений и нейросети](ach.md)

View File

@@ -3,15 +3,27 @@
Меня зовут Рустам. Меня зовут Рустам.
Люблю Linux и все, что связано с ним. Увлекаюсь автоматизацией, аналитикой и программированием, а также смежными
направлениями.
Предпочитаю командную строку графическим Ввиду того, что я часто делаю "*Proof of Concept*" и "*Probe*" проекты, было
приложениям. решено завести для этого блог.
Также увлекаюсь математической статистикой и машинным обучением. Здесь время от времени выкладываю заметки по различным темам, которые мне
показались интересными.
В свободное время, если есть возможность, занимаюсь спортивным туризмом, в # Технологический стэк
частности, горным. В 2019 году взошел на Казбек (5033 м, 2Б к.с.) и в 2021 году
— на Эльбрус (5642 м, 2А к.с.).
# TBD - **Администрирование**: дистрибутивы Linux, права доступа, управление
процессами, **nginx** (веб-сервер), сетевые протоколы, ведение документации
(**mkdocs**);
- **DevOps**: основы **docker** и **ansible**, docker-compose (в т.ч.
Portainer), основы **CI/CD** (GitHub Actions, GitLab CI, Jenkins);
- **Программирование**: **python** (в том числе: numpy, scipy, pandas,
matplotlib), **bash** и zsh, **C/C++**;
- **Математика**: основы теории случайных процессов, машинное обучение,
построение критериев для проверки **гипотез**, численные методы,
моделирование (**метод отбора, MCMC, bootstrap**);
- **Вёрстка**: $\LaTeX$, Markdown, groff, HTML, CSS;
- **Общее**: чтение документации (на русском и английском), **git**,
**терминал** (vim, tmux, различные утилиты командной строки);

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

284
docs/linux/distrant.md Normal file
View File

@@ -0,0 +1,284 @@
# Немного про распределенную компиляцию
## Мотивация / Введение
Мне, как любителю Linux, всегда было интересно изучить Gentoo
Linux. На это есть множество причин, сейчас не о них.
Суть в том, этап установки системы на виртуальную машину пройден и
есть желание попробовать установить на второстепенный маломощный нетбук.
Возникает проблема: Gentoo Linux -- это т.н. "source-based" дистрибутив,
т.е. она распространяется в виде исходного кода. В свою очередь, компиляция
системы на нетбуке занимает чуть больше суток (возможно, это можно поправить
более тщательной конфигурацией перед сборкой, но, на мой взгляд, это
слишком "хардкорный" путь для знакомства с системой). Конечно, компиляция
ядра, строго говоря, необязательна, так как можно поставить предварительно
скомпилированную версию. Но так неинтересно.
Таким образом, возникает вопрос -- можно ли ускорить компиляцию
на слабых ПК? Тут на помощь приходит `distcc`,
своего рода фронтенд для компиляторов C/C++.
Сегодня мы хотим посмотреть на возможность компиляции ядра Linux (минимальной
конфигурации `tinyconfig`) на двух виртуальных машинах с разными
характеристиками. Но для этого нужно рассказать про утилиту `vagrant`,
конфигуратор виртуальных машин.
## Vagrant
Vagrant[^1] (с англ. — «бродяга») — свободное и открытое программное
обеспечение для создания и конфигурирования виртуальной среды разработки.
Является обёрткой для программного обеспечения виртуализации, например
VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и
Puppet.
Данная утилита полезна тем, что позволяет, используя шаблоны виртуальных
машин, запускать их. Для описания стэка требуется один т.н. Vagrantfile.
Она может работать совместно с qemu, VirtualBox, VMWare и пр.
О vagrant стоит знать потому, что в какой момент, эксперементируя с
виртуальными машинами, надоест каждый раз их устанавливать в условном VMWare.
## Distcc
distcc[^2] (от англ. distributed C/C++/ObjC compiler) — инструмент,
позволяющий компилировать исходные коды при помощи
компиляторов C/C++/ObjC на удалённых машинах, что ускоряет процесс компиляции.
Важно понимать, что это своего рода фронтенд для компиляторов,
сам по себе он не компилирует код.
## Компиляция
### Демонстрация стенда
Для начала построчно рассмотрим Vagrantfile.
При его написании используется язык Ruby.
Описание "шаблона" для виртуальных машин. В данном случае это Debian
12 Bookworm.
```ruby
# Default box
box_name = "debian.jessie64.libvirt.box"
```
Файл можно скачать с сайта HashiCorp.
Описание виртуальной машины, на которой будет основная компиляция:
```ruby
# Master
master_node = {
:hostname => "master", :ip => "10.200.1.2", :memory => 1024, :cpu => 1
}
```
Характеристики:
- IP: 10.200.1.2,
- RAM: 1Gb,
- 1 поток.
Они похожи на характеристики моего нетбука, но занижены в целях демонстрации.
Описание второстепенной виртуальной машины:
```ruby
# List of slaves
slaves = [
{ :memory => 4096, :cpu => 4 },
]
```
Характеристики:
- RAM: 4Gb,
- 4 потока.
Скрипт для автоматической установки зависимостей:
```ruby
$distcc_install = <<-SCRIPT
apt update
apt install -y make distcc gcc g++ tmux libz-dev git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison time neofetch
SCRIPT
```
Старт конфигурации виртуальных машин:
```ruby
Vagrant.configure("2") do |config|
```
Конфигурация основной машины:
```ruby
# Master node's config
config.vm.box_check_update = false
config.vm.define master_node[:hostname] do |nodeconfig|
nodeconfig.vm.box = box_name
nodeconfig.vm.hostname = master_node[:hostname]
nodeconfig.vm.network(:private_network, ip: master_node[:ip])
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provision "file", source: "./linux-6.13.tar.gz", destination: "~/linux-6.13.tar.gz"
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = master_node[:memory]
vb.cpus = master_node[:cpu]
end
end
```
В нем:
1. Отключаются обновления,
2. Задаются характеристики ВМ,
3. Запускается скрипт установки зависимостей,
4. Копируется
[архив](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz)
с исходным кодом ядра (должен лежать в директории с Vagrantfile).
Конфигурация второстепенных машин:
```ruby
# Slaves configs
slaves.each_with_index do |slave, i|
config.vm.box_check_update = false
config.vm.define "slave-#{ i+1 }" do |nodeconfig|
# Default box-name (cause I have only it)
nodeconfig.vm.box = box_name
# Hostname: slave-N
nodeconfig.vm.hostname = "slave-#{ i+1 }"
# IP-address: 10.200.1.{N+2}
nodeconfig.vm.network :private_network, ip: "10.200.1.#{ i+3 }"
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = slave[:memory]
vb.cpus = slave[:cpu]
end
end
end
end
```
Стоит обратить внимание, что IP задается автоматически, начиная от
`10.200.1.3` и далее. Сделано это на случай нескольких ВМ.
### Компиляция на одной машине (gcc)
Для начала запустим стенд командой `vagrant up`. На моем ноутбуке это занимает
примерно 127 секунд.
Далее необходимо подключиться к главной машине и распаковать исходники ядра[^3]:
```shell
vagrant ssh master
tar xvf linux-6.13.tar.gz
cd linux-6.13
```
Создаем файл минимальной конфигурации
(с остальными вариантам можно ознакомиться командой `make help | less`):
```shell
make tinyconfig
```
> **Важно**: для чистоты эксперимента все замеры делаются после команды `make
distclean` (см. `make help`).
Запускаем компиляцию с замером времени:
```shell
time -p make CC=gcc
```
### Компиляция на одной машине (distcc)
По смыслу, все тоже самое, только нужно указать distcc, на каких хостах
можно компилировать:
```shell
export DISTCC_HOSTS="localhost"
```
Запускаем компиляцию с замером времени:
```shell
time -p make CC="distcc gcc"
```
### Компиляция на двух машинах (distcc)
Для запуска распределенной компиляции, нужно сначала запустить демон на
второй виртуальной машине. Для этого подключаемся к ней и запускаем его:
```shell
vagrant ssh slave-1
distccd --daemon --allow-private
```
Параметр `--allow-private` разрешает стучаться только с приватных сетей.
Для проверки можно:
1. На второй машине проверить открытые порты: `ss -ntlp | grep 3632`,
2. С основной машины постучаться в этот порт: `telnet 10.200.1.3 3632`
(выход на `C-] C-d`).
Теперь нужно добавить хост, чтобы на нем можно было удаленно компилировать.
Для этого на основной машине:
```shell
export DISTCC_HOSTS="localhost 10.200.1.3"
```
Для проверки можно посмотреть список хостов для компиляции: `distcc --show-hosts`.
Запустим компиляцию на 5 потоках с замером времени:
```shell
time -p make -j5 CC="distcc gcc"
```
Мониторить компиляцию можно с помощью команды (на основной машине):
```shell
watch -n 1 distccmon-text
```
![distccmon-text](assets/distccmon-text.png)
### Таблица сравнения
|Итерация|Одна машина (gcc), с|Одна машина (distcc), с|Две машины (distcc), с|
|:------:|:------------------:|:---------------------:|:--------------------:|
| 1 | 176 | 176 | 111 |
| 2 | 186 | 162 | 109 |
| 3 | 187 | 174 | 127 |
|Среднее | 183 | 170 | 115 |
## Итог
Можно увидеть, что такая параллелизация дает прирост 37%.
Сложно сказать, можно ли разогнать сильнее, так как многое зависит от
правил компиляции (например, их нельзя распараллелить больше чем на 5 потоков).
Очевидно, что распределенная компиляция при прочих равных будет проигрывать
параллельной, так как общение между потоками по определению быстрее.
Но для слабых машин это отлично подходит. К сожалению, у данного метода есть
существенные ограничения:
1. Версии gcc и distcc должны совпадать (хотя, пишут, что достаточно
совпадения только мажорных версий).
2. В некоторых случаях нет возможности общения по TCP и требуется подключение по
SSH. Например, когда есть ограничения безопасности или при сложной организации
сети. Определенно, такое подключение будет медленнее.
Все материалы стенда можно найти в
[репозитории](https://github.com/rustbas/disgrant/) на Github.
[^1]: Википедия [Vagrant](https://ru.wikipedia.org/wiki/Vagrant).
[^2]: Википедия [distcc](https://ru.wikipedia.org/wiki/Distcc).
[^3]: Исходный код ядра можно найти [здесь](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz).

View File

@@ -2,3 +2,5 @@
## 2024-11-01 [Немного про мануалы](manpage.md) ## 2024-11-01 [Немного про мануалы](manpage.md)
## 2025-01-24 [Немного про распределенную компиляцию](distrant.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -1,8 +1,9 @@
# Математика # Математика
# Статистика
## 2024-10-30 [Немного про производящие функции](gen_fun.md) ## 2024-10-30 [Немного про производящие функции](gen_fun.md)
## 2024-09-24 [Немного про Байесовскую статистику](baes.md) ## 2024-09-24 [Немного про Байесовскую статистику](baes.md)
## 2020-09-01 [Немного про проверку гипотез](stat-madness.md)
## 2025-05-30 [Немного про работу с файлами, numpy и предсказаниях](type-pred.md)

199
docs/maths/stat-madness.md Normal file
View File

@@ -0,0 +1,199 @@
# Немного про проверку гипотез
## Введение
Любые статистические испытания зиждятся на проверке гипотез, например:
1. Проверка действия лекарств.
2. Установление зависимости между явлениями.
3. A/B тестирование и пр.
В зависимости от вида данных, целей исследования и других факторов
можно по-разному формулировать гипотезы и по-разному их проверять.
Многое зависит от не только знаний и опыта исследователя, но и в целом
от его подхода. В процессе работы можно все меньше уделять внимание
математической составляющей и все больше полагаться на компьютер и его
вычислительные мощности.
Здесь я хочу рассказать о стадиях, через которые проходит исследователь,
в попытках упростить себе жизнь и ускорить процесс проверки гипотез.
## Небольшой ликбез
В статистике, если упростить, проверку гипотезы можно описать так:
1. По данной выборке считается статистика (т.е. функция от выборки).
2. Из распределения статистики находятся две области, где гипотеза отвергается и где нет. Исходя из этого, принимается решение.
**N.B.** Проверяется гипотеза, модель постулируется.
## Стадия 1. Строгие доказательства
На данной стадии ученый строго выводит распределения статистик, чтобы построить как можно более хорошие критерии.
$$\Large
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S} =
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{\sigma} \cdot
\frac{1}
{\frac{S}{\sigma}} =
$$
$$\Large
= \sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{\sigma} \cdot
\frac{1}
{\sqrt{\frac{(n-1)S^2}{\sigma^2}\cdot
\frac{1}{n-1}
}}
$$
Получим:
$$\Large
\begin{matrix}
&\sqrt{n}
\frac{\overline{\mathbb{X}} - \mu}
{\sigma} &\sim &N(0,1) \\
&\frac{(n-1)S^2}{\sigma^2} &\sim &\chi^2(n-1)
\end{matrix}
$$
Таким образом, по [определению](https://ru.wikipedia.org/wiki/Распределение_Стьюдента#Определение):
$$\Large
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S} \sim t(n-1).
$$
## Небольшой пример (критерий Стьюдента)
**Дано**: выборка Х объема 10
$$\Large
\mathbb{X} = \left(
\begin{matrix}
3.175 \\
4.042 \\
2.127 \\
3.841 \\
1.699 \\
2.223 \\
3.211 \\
3.33 \\
2.447 \\
2.904
\end{matrix}
\right)
$$
**Модель**: $N(\mu, \theta_2)$
**Нулевая гипотеза**: $\mu = 3$
**Решение**:
Статистика критерия:
$$\Large
T(\mathbb{X}) =
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S}
\sim
t(n-1)
$$
Статистика равна:
$$\Large
T(\mathbb{X}) = -1.9066
$$
Пусть уровень значимости $\alpha = 0.05$.
Область, где не отвергается нулевая гипотеза: $(g_1, g_2) = (-2.262, 2.262)$, т.е. это область, которую принимает значение статистики при условии верности нулевой гипотезы с вероятностью $1 - \alpha = 0.95$. $g_1$ в данном случае это $0.025$-квантиль, а $g_2$, соотвественно, 0.975-квантиль.
![Доверительный интервал](assets/stat-madness/conf_interval.png)
Красным обозначен интервал $(g_1, g_2)$
Таким образом, нулевая гипотеза не отвергается, так как значение статистики лежит в данном интервале.
> **Примечание**: можно было выбрать доверительный интервал иначе,
> но его стараются выбрать так, чтобы минимизировать его длину.
## Стадия 2. Открытие моделирования
Иногда (вернее, даже как правило) распределение статистики вывести
невозможно. В таком случае пользуются моделированием. Идея в том, что
нам известно распределение выборки в случае нулевой гипотезы. Таким
образом, можно многократно генерировать выборки и считать статистику,
таким образом получив ее распределение.
![Открытие моделирования](assets/stat-madness/modeling.png)
В данном случае, моделирование выборки проводилось
в условиях $X \sim N(\mu, S^2)$.
Можно увидеть некоторое расхождение. В этом, кстати, заключается интересный
момент. Часто критикуются исследования построенные на моделировании, так как
есть ненулевая (хоть и очень маленькая) вероятность, что выборки
сгенерировались так, что полученное распределение статистики плохо отражает
реальность.
## Стадия 3. Бутстрэп
Бывают случаи, когда распределение выборки неизвестно совсем
(или его сложно/нельзя в обычном смысле генерировать,
[пример](https://stepik.org/lesson/40491/step/1?unit=24794)). В таком случае
постулируют, что данная выборка хорошо отражает генеральную совокупность и в
качестве функции распределения берут эмпирическую функцию распределения.
$$\Large
F_n(x) = \frac
{\sum_{i=1}^{n} \mathbb{1}(x)}
{n}
$$
где:
$$\Large
\mathbb{1}(x) =
\begin{cases}
1, x > X_i, \\
0, \text{ иначе.}
\end{cases}
$$
В итоге, получается, что для проверки гипотез не нужно ничего кроме выборки и выдуманной статистики (которая, вообще, может быть любой, от нее зависит только качество получаемого критерия).
Основная идея заключается в том, чтобы генерировать выборки объемом как и данная выборка из следующего распределения:
$$\Large
\mathcal{F} =
\begin{pmatrix}
X_1 &X_2 &\cdots &X_n \\
\frac{1}{n} &\frac{1}{n} &\cdots &\frac{1}{n}
\end{pmatrix}.
$$
![Результат на выборке объема 10](assets/stat-madness/bootstrap.png)
Таким образом, из расхождения графиков можно сделать следующие выводы:
- применение бутстрэпа требует большой объема первоначальной выборки,
- наблюдения в выборке должны быть независимыми.
Несмотря на это, он часто применяется невпопад, так как не требует особых затрат на реализацию.

166
docs/maths/type-pred.md Normal file
View File

@@ -0,0 +1,166 @@
# Немного про работу с файлами, numpy и предсказаниях
## Введение
Известно, что файлы в памяти представлены последовательностью байтов.
Структурно, эта последовательность может быть разной. Она может
содержать только ASCII-текст, текст с любой кодировкой, сжатый архив,
mp3, etc. При взаимодействии с файлом (например, открыть файл
текстовым редактором), операционная система не смотрит на
т.н. **расширение файла**, её интересует *побайтовое* содержание
файла.
В Unix для определения типа файла есть утилита `file`. Как она
определяет тип я точно не знаю, но могу сказать, что частично метод
основан на *"заголовке"* файла (первых байтах).
Пример работы `file` на исполняемом файле:
```
./program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, ...
```
Шестнадцатеричное представление (первые несколько строк) с помощью
`xxd`:
```console
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 6010 0000 0000 0000 ..>.....`.......
00000020: 4000 0000 0000 0000 c036 0000 0000 0000 @........6......
00000030: 0000 0000 4000 3800 0d00 4000 1f00 1e00 ....@.8...@.....
```
В начале видно последовательность `ELF` -- формат исполняемых файлов в
Unix[1].
Возникает вопрос: **есть какой-то паттерн для различных типов файлов,
который можно увидеть, не считая специальных симвовол в *заголовке*?**
Можно усложнить вопрос: можно ли по какому-то обобщению (*сигнатуре*)
файла предсказать его тип? Попробуем это выяснить.
Для этого нужно решить следующие задачи:
1. Написать модуль (**на Си**), который по имени файла просчитывает
сигнатуру и возвращает её;
2. Посмотреть, как выглядят эти сигнатуры;
3. Попробовать обучить простую нейросеть.
## Как считать сигнатуру файла
Возьмем нулевую матрицу `M` размера 256х256, так как один байт это
число от 0 до 255. Считаем файл в память в виде последовательности
байтов. Теперь будем двигаться по последовательности с окном
размера 2. В этом окне первый элемент будет отвечать за номер строки,
а второй за номер столбца. И каждый раз с окном `(x, y)` будем
увеличивать элемент матрицы `M[x][y]` на единицу.
![](./assets/type-pred/file_sig.png)
## Причины использования Си
Если **кратко**: python очень медленный. Например, средний `wav`-файл
занимает около 10 мегабайт. Это порядка десяти миллионов байт, по
которым нужно пробежать и заполнить матрицу. А для обучения нейросети,
таких файлов должно быть много.
**Отдельный интерес**, также, представляет возможность написать модуль
для python на C, который умеет взаимодействовать с API библиотеки
NumPy.
## Чтение файлов в память
Для чтения файла в память, был написан модуль на Си, доступный
репозитории[2]. Здесь кратко опишу, как он работает.
В нем реализована функция `signature_from_filepath_by2`, которая
получает на вход два параметра: имя файла и уровень `verbose`. `by_2`
в названии обусловлено тем, что работа не с матрицами, а `n`-мерными
тензорами улучшает качество предсказания.
Функция `read_file` считывает файл в структуру `raw_data`, которая
представляет собой просто последовательность байтов и размер этой
последовательности. После этого функция `build_matrix` считывает по
этой струтуре сигнатуру и записывает в `matrix`.
Далее создается объект `PyObject *result`, представляющий собой
указатель на массив `NumPy` типа `uint32`. На его основе создается
динамический массив `result_data`.
Так как `matrix` лежит в памяти последовательно (ввиду того, что
она аллоцирована на стеке), то её можно просто скопировать в
`result_data`. После всего этого возвращается указатель `*result`.
Помимо этого в коде много второстепенных действий, которые требует API
Python для работы. Эти подробности я опустил, их можно увидеть в коде,
все достаточно предсказуемо.
## Пайплайн обучения нейросети
**Нюанс обучения нейросети**: так как получившиеся матрицы вышли очень
неравномерными, дополнительно они были размыты [*методом
Гаусса*](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%BC%D1%8B%D1%82%D0%B8%D0%B5_%D0%BF%D0%BE_%D0%93%D0%B0%D1%83%D1%81%D1%81%D1%83).
Для обучения нейросети необходимо создать матрицу меток. Так как
предполагается, что нейросеть будет предсказывать различные типы
файлов, то матрица меток будет иметь размер `M*NxM`, где:
- `M` -- количество типов файлов
- `N` -- количество файлов в одном типе (берется минимальное из всех,
чтобы обучение было равномерным)
Для разбиения на тренировочную и обучающию выборки отлично подходит
функция `train_test_split` из модуля `sklearn.model_selection`.
Сам перцептрон будет иметь следующую архитектуру:
1. На входном слое будет 65536 нейронов (`256х256`). Функцией активации
будет `ReLu`-функция.
2. Скрытый слой будет иметь 512 нейронов и `sigmoid`-функцию активации.
3. На выходе будет столько нейронов, сколько типов файлов нужно будет
предсказать.
Для для задания `loss`-функции и оптимизатора:
```python
loss_fn = nn.CrossEntropyLoss()
optimizer = t.optim.SGD(model.parameters(), lr=1e-3)
```
Цикл обучения в данном случае состоял из 250 эпох.
Пайплайн обучения можно будет найти в репозитории
[проекта](https://github.com/rustbas/filetype-prediction), вместе с
инструкцией по воспроизведению результатов (кроме того факта, что
файлы различных типов нужно будет скачать самому).
## Результаты и картинки
Усреденные сигнатуры различных типов файлов можно увидеть ниже.
![](./assets/type-pred/heatmaps.png)
Также, показатели обучения:
![](./assets/type-pred/stats.png)
## Выводы
По итогу, можно сказать, что в некоторых случаях, *сигнатура* файла
является неплохим предиктором его типа.
Гипотетически, это можно использовать для следующих идей:
1. Восстановление частично поврежденных файлов, так как можно попытаться
угадать его структуру и восстановить её.
2. Определение исполняемых файлов при анализе вредоносного ПО.
3. Обнаружение скрытых данных (когда сигнатура файла и его тип не
соответствуют друг другу).
## Источники
1. [Википедия про ELF-формат](https://ru.wikipedia.org/wiki/Executable_and_Linkable_Format);
2. [Репозиторий проекта](https://github.com/rustbas/filetype-prediction);
3. [Основание идеи заметки](https://youtu.be/AUWxl0WdiNI?si=mklboGVUC-mZ-d1M);
1. [Пояснение про сигнатуру](https://youtu.be/4bM3Gut1hIk?si=zSGWLHKTKW7bStPb);
4. [Модули для Python](https://youtu.be/45TOazYbedI?si=jykTbnbjcyzTsN0r).

View File

@@ -3,23 +3,45 @@ site_url: https://rustbas.github.io/blog
repo_url: https://github.com/rustbas/blog repo_url: https://github.com/rustbas/blog
edit_uri: edit/main/docs/ edit_uri: edit/main/docs/
theme: theme:
name: terminal name: material
palette: dark palette:
- scheme: default
toggle:
icon: material/toggle-switch
name: Switch to dark mode
primary: green
- scheme: slate
toggle:
icon: material/toggle-switch-off-outline
name: Switch to light mode
primary: teal
features: features:
- revision.date - navigation.instant # TODO: check troubles with TeX loading
- revision.history - navigation.instant.progress
- navigation.side.hide - header.autohide
icon:
repo: fontawesome/brands/git
font:
# text: Roboto
code: JetBrains Mono
# - revision.date
# - revision.history
# - navigation.side.hide
nav: nav:
# - "Обо мне": 'index.md' # - "Обо мне": 'index.md'
- "Математика": 'maths/index.md' - "Математика": 'maths/index.md'
- "Linux": 'linux/index.md' - "Linux": 'linux/index.md'
- "Общее": 'common/index.md'
plugins: plugins:
- search: - search:
lang: ["ru", "en"] lang: ["ru", "en"]
indexing: 'full' indexing: 'full'
- git-revision-date - git-revision-date
markdown_extensions: markdown_extensions:
- pymdownx.arithmatex: - pymdownx.arithmatex:
generic: true generic: true