Data Science блог с помощью fastpages
Как запустить свой DS/ML/AI/Tech блог с минимумом сложностей связанных с хостингом и деплойем этого блога.
- Создание блога с помощью fastpages и GitHub
- Настройка блога
- Публикация постов из .ipynb с помощью fastpages
- Как fastpages конвертирует исходные файлы посты
- fast_template - младший брат fastpages
- Плюсы и минусы
- Резюме
- DS/ML/AI блоги
- Полезные ссылки
В конце февраля 2020 года ребята из fast.ai
представили миру fastpages
- платформу для ведения блога. Отмечу, что fastpages
основан на Jekyll
, о котором на Хабре есть множество постов.
Примером блога на движке fastpages
является данный блог.
Главное отличительная черта и преимущество fastpages
состоит в поддерживаемых из коробки форматах постов:
- Jupyter ноутбуки (расширение
.ipynb
); - Markdown файлы (расширение
.md
); - Word файлы (расширение
.docx
)
Таким образом, автору блога необходимо сохранить пост в любом из перечисланных выше форматах в соответствующей директории:
- './_notebooks/' для
.ipynb
; - './_posts/' для
.md
; - './_word/' для
.docx
.
А все остальное сделает fastpages
, как утверждают его авторы.
fastpages
использует Github Pages для хостинга и Github Actions для автоматизации публикации постов.
Как я понимаю, fastpages
является доработкой связки Github Pages + Jekyll
, где можно сразу же из Jupyter ноутбука получить опубликованный пост.
fastpages
и GitHub
Создание блога с помощью Если хотите самостоятельно разобраться, то вот официальная инструкция по настройке в репозитории fastpages
.
Процесс настройки fastpages
:
- Создать собственную копию репозитория из шаблона
fastpages
по ссылке - Далее автоматически откроется pull request (через ~ 30 секунд), который отвечает за настройку вашего блога, чтобы он мог начать работать.
- Вам нужно выполнить инструкции из полученного pull request'a и вы получите свою собственную уже работающую платформу для блога.
Видео туториал
Настройка блога
Есть возможность для персонализированной конфигурации вашего блога. Параметры конфигурации находятся в файле ./_config.yml
, некоторые из них приведены ниже:
-
title
- название вашего блога, которое отображается в верхнем левом углу на каждой странице; -
description
- описание, которое будет отображаться в разных местах при предварительном просмотре вашего сайта (например, в социальных сетях); -
github_username
- позволяет вашему сайту отображать ссылку на вашу страницу GitHub в нижнем колонтитуле; -
github_repo
- позволяет вашему сайту отображать ссылки на ваш репозиторий для различных функций, таких как ссылки на GitHub, Google Colab и Binder для Jupyter ноутбуков; -
default_badges
- по умолчанию ссылки GitHub, Google Colab и Binder будут отображаться в постах созданных из Jupyter ноутбуков. Вы можете задать, какие из них будут отображаться по умолчанию, установив для соответствующего значения вdefault_badges
значениеtrue
илиfalse
. Например, если вы хотите отключить ссылки на Binder, вы должны поправитьdefault_badges
:default_badges: github: true binder: false colab: true
-
url
- это не нужно менять, если у вас нет собственного домена; -
baseurl
- см. комментарии в /_config.yml для получения инструкций ("Special Instructions for baseurl"). Если у вас нет настраиваемого домена, вы можете игнорировать эту опцию; -
twitter_username
- создает ссылку в нижнем колонтитуле на страницу Twitter; -
use_math
- установите значениеtrue
, чтобы получить поддержку математических формулLaTeX
; -
show_description
- отображает на домашней странице описание под заголовком ваших постов в блоге. По умолчанию установлено значениеtrue
; -
google_analytics
- опционально можно использовать идентификатор Google Analytics; -
pagination
- максимальное количество постов, отображаемых на каждой странице вашей домашней страницы. Значение по умолчанию равно 15. Когда число постов превысит заданное значение, тогда произойдет разбивка на страницы, которая выглядит так: -
show_tags
- включает отображение тегов внутри постов, которые выглядят следующим образом: -
show_image
- при значенииtrue
включается возможность добавления изображений к постам на домашней странице. Выглядит следующим образом (первые 2 поста сопровождаются изображениями):
.ipynb
с помощью fastpages
Публикация постов из -
Сохраните исходный файл вашего поста (в одном из форматов:
.ipynb
,.md
или.docx
) в соответствующей папке репозитория (./_notebooks
,./_posts
или./_word
). Пример имени для поста2020-05-26-DS-fastpages-blog.ipynb
. Такое наименование является необходимым для отображения поста движком Jekyll (больше деталей).Важные аспекты наименования постов:
- Вначале имени поста указывается дата в формате
YYYY-MM-DD-
; - Символ, следующий сразу за тире, должен быть буквой алфавита.
- Вначале имени поста указывается дата в формате
- Сделайте commit и push ваших файлов на удаленный репозиторий GitHub в ветку
master
. -
GitHub автоматически конвертирует ваши файлы в посты блога. Процесс конвертации займет ~5 минут. Можно перейти на вкладку «Actions» в репозитории на GitHub. Вы увидите три workflow, которые запускаются при каждом
push
в веткуmaster
:- Check Configurations - процесс проверки ваших файлов (например, ссылок на изображения), перед обновлением контента в блоге;
- CI - процесс непрерывного деплоя вашего блога;
-
GH Pages Status - процесс проверки доступа к блогу.
Если эти процессы завершаются зеленой галочкой для последнего коммита, то сайт блога успешно обновился.
-
Для предварительного локального просмотра того, как ваш блог будет выглядеть, см. этот раздел.
Ниже представлены различные возможности форматирования, которые fastpages
поддерживает из коробки.
Возможности форматирования постов
Первая ячейка в вашем Jupyter ноутбуке (а также первые строки в Markdown файлах) содержит метаданные, которые могут включать/выключать опции связанные с постом.
# "Title"
> "Awesome summary"
- toc:true- branch: master
- badges: true
- comments: true
- author: Hamel Husain & Jeremy Howard
- categories: [fastpages, jupyter]
Для указания таких в Markdown файлах необходимо в начале файла задать опции как и в ноутбуке, только поместив эти метаданные между строк содержащих по три минуса, т.е. ---
.
Выглядит это так:
---
title: "Title"
description: "Awesome description"
toc: true
layout: post
categories: [markdown]
---
- title: "Deep learning: A tutorial"
Перечень управляющих конструкций для форматирования поста (взято отсюда):
-
toc
- при значенииtrue
автоматически будет сгенерировано оглавление поста из заголовков, обозначенных Markdown разметкой; -
badges
[notebooks only] - при значенииtrue
отображаются ссылкиGoogle Colab
,Binder
иGitHub
, не работает при приватном репозитории; -
hide_github_badge
[notebooks only] - при значенииtrue
скроет ссылку наGitHub
; -
hide_colab_badge
[notebooks only] - при значенииtrue
скроет ссылку наGoogle Colab
; -
hide_binder_badge
[notebooks only] - при значенииtrue
скроет ссылку наBinder
; -
branch
[notebooks only] - используется для дополнительной ссылки на ваш Jupyter ноутбук на Colab и GitHub. Значение по умолчанию:master
; -
comments
- при значенииtrue
будут включены комментарии (больше деталей); -
author
- при значенииtrue
отображаются имена авторов; -
categories
- позволяют группировать посты по тегам (на странице "Tags"). -
image
- задает изображение для поста, которое будет отображаться на главной странице блога и в соц. сетях (Twitter) вместе с ссылкой на пост:- пример задания изображения к посту -
images/figure.png
; - изображение обязательно должно находиться внутри папке
/images
вашего репозитория;
- пример задания изображения к посту -
-
search_exclude
- позволяет скрывать пост в поиске блога (страницаSearch
), стоит заменить, поиск работает только с латиницей; -
hide
- при значенииtrue
пост будет скрыт на главной странице блога, но будет доступен по прямой ссылке:- рекомендуется использовать permalinks для создания предсказуемых ссылок на сам пост;
- если
search_exclude
будет иметь значениеtrue
, то пост можно будет найти через поиск блога (страницаSearch
);
-
sticky_rank
- позволяет закрепить пост на конкретной позиции, задав ему порядковый номер. Если двум постам задать одинаковый номер, то между собой они будут отсортированы по дате.
Скрытие и сворачивание кода
Приятной функциональностью этого движка для блога является возможность скрывать код и/или результаты его выполнения. Это позволяет не нагружать посты отображением простыни кода или огромного количество принтов (что бывает при обучении нейросетей по эпохам), скрывая эти большие по размеру элементы, но не выкидывая их из поста на совсем.
Комментарий #hide
в первой строке любой ячейки кода будет скрывать как ввод, так и вывод этой ячейки.
Ниже есть ячейка, которая не отображается в посте, но присутствует в исходном jupyter ноутбуке. Можете проверить на GitHub.
Комментарий #hide_input
в первой строке любой ячейки кода будет скрывать только ввод этой ячейки.
Поместив флаг #collapse-hide
, в первую строку любой ячейки, вы скроете код этой ячейки внутри поста. Но в замен появится кнопка, позволяющая показать эту ячейку.
#collapse-hide
import altair as alt
import pandas as pd
import numpy as np
Флаг #collapse-show
позволяет показать ячейку по умолчанию, но дает читателю возможность скрыть ее.
#collapse-show
np.random.seed(42)
source = pd.DataFrame(
np.cumsum(np.random.randn(100, 3), 0).round(2),
columns=['A', 'B', 'C'],
index=pd.RangeIndex(100, name='x')
)
source = source.reset_index().melt('x', var_name='category', value_name='y')
Altair
Интерактивные графики с помощьюГрафики построенные с помощью библиотеки Altair внутри поста остаются интерактивными как в ноутбуке.
#collapse-hide
# код отсюда: https://altair-viz.github.io/gallery/multiline_tooltip.html
# Create a selection that chooses the nearest point & selects based on x-value
nearest = alt.selection(type='single', nearest=True, on='mouseover',
fields=['x'], empty='none')
# The basic line
line = alt.Chart(source).mark_line(interpolate='basis').encode(
x='x:Q',
y='y:Q',
color='category:N'
)
# Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = alt.Chart(source).mark_point().encode(
x='x:Q',
opacity=alt.value(0),
).add_selection(
nearest
)
# Draw points on the line, and highlight based on selection
points = line.mark_point().encode(
opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)
# Draw text labels near the points, and highlight based on selection
text = line.mark_text(align='left', dx=5, dy=-5).encode(
text=alt.condition(nearest, 'y:Q', alt.value(' '))
)
# Draw a rule at the location of the selection
rules = alt.Chart(source).mark_rule(color='gray').encode(
x='x:Q',
).transform_filter(
nearest
)
# Put the five layers into a chart and bind the data
alt.layer(
line, selectors, points, rules, text
).properties(
width=600, height=300
)
source.head()
Вставка изображений
Вы можете добавлять изображения с подписями следующим образом:

Напомню, что подписи опциональны, и что изображения можно указывать как локально (в рамках репозитория блога), так и находящиеся в открытом доступе (имею в виду интернет).
Видео Youtube
Чтобы красиво вставить видео с Youtube достаточно использовать конструкцию:
> youtube: https://youtu.be/L0boq3zqazI
Видео туториал по настройке блога прикреплен именно таким образом.
Посты из Twitter
Есть возможность отображать посты из Twitter.
Например, ссылка на этот пост > twitter: https://twitter.com/jakevdp/status/1204765621767901185?s=20
отобразит слудущее:
Altair 4.0 is released! https://t.co/PCyrIOTcvv
— Jake VanderPlas (@jakevdp) December 11, 2019
Try it with:
pip install -U altair
The full list of changes is at https://t.co/roXmzcsT58 ...read on for some highlights. pic.twitter.com/vWJ0ZveKbZ
LaTeX
формулы
Jupyter ноутбуки поддерживают синтаксис LaTeX
формул. Чтобы формулы отображались в постах, нужно убедиться, что опция use_math
включена внутри _config.yml
(см. Настройка блога).
Следуюший LaTeX
код:
$$L(\theta) = \frac{1}{N} \sum_i^N{(y_i - \hat{y_i})^2} \rightarrow \min_{\theta}$$
будет отображен таким образом:$$L(\theta) = \frac{1}{N} \sum_i^N{(y_i - \hat{y_i})^2} \rightarrow \min_{\theta}$$
Примечания
Есть возможность отображать примечания различных типов.
Предупреждение: > Warning: There will be no second warning!
Важно: > Important: Pay attention! It's important.
Подсказка: > Tip: This is my tip.
Заметка: > Note: Take note of this.
Если вставить в любое из примечаний ссылку, то она будет работать.
Например,
> Note: A doc link to [an example website: fast.ai](https://www.fast.ai/) should also work fine.
отобразится так:
Отображение Emoji
Если написать Сейчас будет эмоджи :robot:.
, то получится
Сейчас будет эмоджи .
Шпаргалка по Emoji.
Сноски
В jupyter ноутбуках можно использовать сноски, однако синтаксис отличается от Markdown разметки. Это руководство содержит более подробную информацию об этом синтаксисе, который выглядит следующим образом:
For example, here is a footnote {% fn 1 %}.
And another {% fn 2 %}
{{ 'This is the footnote.' | fndetail: 1 }}
{{ 'This is the other footnote. You can even have a [link](https://fastpages.fast.ai/jupyter/2020/02/20/test.html#Footnotes)' | fndetail: 2 }}
For example, here is a footnote 1. And another 2
1. This is the footnote.↩
fastpages
конвертирует исходные файлы посты
Как Для этого fastpages
использует nbdev для преобразования jupyter ноутбуков, word и .md
файлов в посты блога. После того, как вы сохраните исходные файлы своих постов в папках /_notebooks
, /_word
или /_posts
, то GitHub Actions c помощью nbdev автоматически преобразует их в конечный вид, в котором посты отображаются на сайте вашего блога.
fast_template
- младший брат fastpages
Стоит упомянуть, что ранее fast.ai
выпустили аналогичный проект под названием fast_template, который еще проще в настройке, но не поддерживает автоматическое создание постов из Word и Jupyter файлов, а также многие другие функции перечисленные выше. Поскольку fastpages
более гибок и расширяем, его авторы рекомендуют использовать его там, где это возможно.
Авторы предполагают, что fast_template
может быть лучшим вариантом для тех, кто ведет не технические блоги. В этом случае посты можно создавать только с помощью встроенного онлайн-редактора Github, не заморачиваясь с использованием git
.
Плюсы и минусы
Что понравилось
- простота создания и размещения блога и публикации контента;
- возможность публиковать Jupyter ноутбуки в качестве постов + удобства оформления:
- поддержка отображения интерактивных графиков;
- скрытие/сворачивание кода;
- поддержка отображения GIF-анимации;
- интеграция видео с youtube и тд.
- нет зависимости от сторонней платформы по типу Medium;
- возможность разместить блог по собственному url;
- параметр
badges
в метаинформации к посту позволяет прикрепить ссылки наGitHub
,Binder
,Google Colab
, что позволяет сразу перейти от поста к коду и его исполнению; - комментарии для блога из коробки;
- возможность прикрепить пост на конкретуню позицию на общей странице с помощью
sticky_rank
, смотреть тут; - отсутствие сторонней рекламы;
Что не понравилось или вызывало вопросы
- непонятно, как сделать структурированный блог с вложенностью:
- возможное решение permalinks];
- структура нужна для объединения нескольких постов общей темой;
- хочется структуру, чтобы в одной директорий хранить все, что связанно с постом (данные, изображения для ноутбуков) в одной папке, а не искать их в куче общих файлов и не городить какую-то структуру в этих общих для всех постов папках.
- нет WYSIWYG (What You See Is What You Get):
-
Jekyll
его и не подразумевает из коробки; - возможен локальный запуск блога;
-
- в
Jekyll
в заголовке и описании поста не поддерживаются обратные кавычки, квадратные скобки и тд. -
Jekyll
подразумевает использованиеgit
для публикации постов; - целесообразность хранения Jupyter ноутбуков в репозитории под вопросом;
- непонятно, как привязать spell checker для Jupyter ноутбуков.
Резюме
Команда fast.ai предложили DS сообществу интересный и достаточно функциональный инструмент для ведения блога, автору которого остается думать только о том, какой контент публиковать.
Сложность использования практически минимальная, нужны базовые знания git
, разметки Markdown и Jupyter Notebook. И никаких проблем с тем, как и где хостить и деплоить сам блог.
Конечно, есть определенные пожелания по поводу функционала этого движка, для этого можно участвовать в развитии проекта, находя баги или предлогая те или иные улучшения. В последнем случае даже pull request
не обязателен, порой хватает текстового описание тех или иных желаний пользователей.
В заключение хочу сказать, что сам пользуюсь и всем советую.
DS/ML/AI блоги
-
Пример блога на
fastpages
by Scott H. Hawley; - Анализ малых данных блог Александра Дьяконова;
- Andrej Karpathy github.io, medium;
- Machine Learning Mastery by Jason Brownlee;
Блоги компаний
- Fast.ai + fastpages blog;
- Airbnb;
- Uber;
- OpenAI;
- DeepMind;
- Nvidia + AI podcast;
- Microsoft AI blog + ML devblogs
Полезные ссылки
-
Репозиторий проекта
fastpages
; - Introducing fastpages;
-
Туториал с примерами того, что можно сделать в
.ipynb
посте; -
Репозиторий проекта
fast_template
+ статья от fast.ai; -
Домашняя страница проекта
nbdev
+ репозиторий + форум; - Достаточно широкий обзор движков для блога;
- Еще блоги [1, 2];