add website
Browse files- README.md +1 -2
- _config.yml +1 -0
- _site/404.html +86 -0
- _site/about/index.html +87 -0
- _site/assets/main.css +196 -0
- _site/assets/minima-social-icons.svg +33 -0
- _site/feed.xml +17 -0
- _site/index.html +76 -0
- _site/jekyll/update/2021/10/19/welcome-to-jekyll.html +99 -0
- _site/large-scale-demo/index.html +78 -0
- _site/main-training/index.html +78 -0
- efficient_training.ipynb +0 -0
- header-animate.js +225 -0
- index.html +477 -0
- join-main-training.md +5 -0
- logos/hse.png +0 -0
- logos/huggingface.png +0 -0
- logos/stream.gif +0 -0
- logos/uwash.png +0 -0
- logos/yandex.png +0 -0
- quantization/quant.py +144 -0
- style.css +145 -0
README.md
CHANGED
@@ -3,8 +3,7 @@ title: Test Demo
|
|
3 |
emoji: 🔥
|
4 |
colorFrom: indigo
|
5 |
colorTo: red
|
6 |
-
sdk:
|
7 |
-
app_file: app.py
|
8 |
pinned: false
|
9 |
---
|
10 |
|
|
|
3 |
emoji: 🔥
|
4 |
colorFrom: indigo
|
5 |
colorTo: red
|
6 |
+
sdk: static
|
|
|
7 |
pinned: false
|
8 |
---
|
9 |
|
_config.yml
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
theme: jekyll-theme-cayman
|
_site/404.html
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>Your awesome title | Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="Your awesome title" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
11 |
+
<meta property="og:description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/404.html" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/404.html" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta name="twitter:card" content="summary" />
|
16 |
+
<meta property="twitter:title" content="Your awesome title" />
|
17 |
+
<script type="application/ld+json">
|
18 |
+
{"@type":"WebPage","headline":"Your awesome title","url":"http://localhost:4000/404.html","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","@context":"https://schema.org"}</script>
|
19 |
+
<!-- End Jekyll SEO tag -->
|
20 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
21 |
+
<body><header class="site-header" role="banner">
|
22 |
+
|
23 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
24 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
25 |
+
<label for="nav-trigger">
|
26 |
+
<span class="menu-icon">
|
27 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
28 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
29 |
+
</svg>
|
30 |
+
</span>
|
31 |
+
</label>
|
32 |
+
|
33 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
34 |
+
</nav></div>
|
35 |
+
</header>
|
36 |
+
<main class="page-content" aria-label="Content">
|
37 |
+
<div class="wrapper">
|
38 |
+
<style type="text/css" media="screen">
|
39 |
+
.container {
|
40 |
+
margin: 10px auto;
|
41 |
+
max-width: 600px;
|
42 |
+
text-align: center;
|
43 |
+
}
|
44 |
+
h1 {
|
45 |
+
margin: 30px 0;
|
46 |
+
font-size: 4em;
|
47 |
+
line-height: 1;
|
48 |
+
letter-spacing: -1px;
|
49 |
+
}
|
50 |
+
</style>
|
51 |
+
|
52 |
+
<div class="container">
|
53 |
+
<h1>404</h1>
|
54 |
+
|
55 |
+
<p><strong>Page not found :(</strong></p>
|
56 |
+
<p>The requested page could not be found.</p>
|
57 |
+
</div>
|
58 |
+
|
59 |
+
</div>
|
60 |
+
</main><footer class="site-footer h-card">
|
61 |
+
<data class="u-url" href="/"></data>
|
62 |
+
|
63 |
+
<div class="wrapper">
|
64 |
+
|
65 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
66 |
+
|
67 |
+
<div class="footer-col-wrapper">
|
68 |
+
<div class="footer-col footer-col-1">
|
69 |
+
<ul class="contact-list">
|
70 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
71 |
+
</div>
|
72 |
+
|
73 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<div class="footer-col footer-col-3">
|
77 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
78 |
+
</div>
|
79 |
+
</div>
|
80 |
+
|
81 |
+
</div>
|
82 |
+
|
83 |
+
</footer>
|
84 |
+
</body>
|
85 |
+
|
86 |
+
</html>
|
_site/about/index.html
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>About | Your awesome title</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="About" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
11 |
+
<meta property="og:description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/about/" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/about/" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta name="twitter:card" content="summary" />
|
16 |
+
<meta property="twitter:title" content="About" />
|
17 |
+
<script type="application/ld+json">
|
18 |
+
{"@type":"WebSite","headline":"About","url":"http://localhost:4000/about/","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","name":"Your awesome title","@context":"https://schema.org"}</script>
|
19 |
+
<!-- End Jekyll SEO tag -->
|
20 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
21 |
+
<body><header class="site-header" role="banner">
|
22 |
+
|
23 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
24 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
25 |
+
<label for="nav-trigger">
|
26 |
+
<span class="menu-icon">
|
27 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
28 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
29 |
+
</svg>
|
30 |
+
</span>
|
31 |
+
</label>
|
32 |
+
|
33 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
34 |
+
</nav></div>
|
35 |
+
</header>
|
36 |
+
<main class="page-content" aria-label="Content">
|
37 |
+
<div class="wrapper">
|
38 |
+
<article class="post">
|
39 |
+
|
40 |
+
<header class="post-header">
|
41 |
+
<h1 class="post-title">About</h1>
|
42 |
+
</header>
|
43 |
+
|
44 |
+
<div class="post-content">
|
45 |
+
<p>This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at <a href="https://jekyllrb.com/">jekyllrb.com</a></p>
|
46 |
+
|
47 |
+
<p>You can find the source code for Minima at GitHub:
|
48 |
+
<a href="https://github.com/jekyll">jekyll</a> /
|
49 |
+
<a href="https://github.com/jekyll/minima">minima</a></p>
|
50 |
+
|
51 |
+
<p>You can find the source code for Jekyll at GitHub:
|
52 |
+
<a href="https://github.com/jekyll">jekyll</a> /
|
53 |
+
<a href="https://github.com/jekyll/jekyll">jekyll</a></p>
|
54 |
+
|
55 |
+
|
56 |
+
</div>
|
57 |
+
|
58 |
+
</article>
|
59 |
+
|
60 |
+
</div>
|
61 |
+
</main><footer class="site-footer h-card">
|
62 |
+
<data class="u-url" href="/"></data>
|
63 |
+
|
64 |
+
<div class="wrapper">
|
65 |
+
|
66 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
67 |
+
|
68 |
+
<div class="footer-col-wrapper">
|
69 |
+
<div class="footer-col footer-col-1">
|
70 |
+
<ul class="contact-list">
|
71 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
72 |
+
</div>
|
73 |
+
|
74 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
<div class="footer-col footer-col-3">
|
78 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
79 |
+
</div>
|
80 |
+
</div>
|
81 |
+
|
82 |
+
</div>
|
83 |
+
|
84 |
+
</footer>
|
85 |
+
</body>
|
86 |
+
|
87 |
+
</html>
|
_site/assets/main.css
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** Reset some basic elements */
|
2 |
+
body, h1, h2, h3, h4, h5, h6, p, blockquote, pre, hr, dl, dd, ol, ul, figure { margin: 0; padding: 0; }
|
3 |
+
|
4 |
+
/** Basic styling */
|
5 |
+
body { font: 400 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; color: #111; background-color: #fdfdfd; -webkit-text-size-adjust: 100%; -webkit-font-feature-settings: "kern" 1; -moz-font-feature-settings: "kern" 1; -o-font-feature-settings: "kern" 1; font-feature-settings: "kern" 1; font-kerning: normal; display: flex; min-height: 100vh; flex-direction: column; }
|
6 |
+
|
7 |
+
/** Set `margin-bottom` to maintain vertical rhythm */
|
8 |
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre, ul, ol, dl, figure, .highlight { margin-bottom: 15px; }
|
9 |
+
|
10 |
+
/** `main` element */
|
11 |
+
main { display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ }
|
12 |
+
|
13 |
+
/** Images */
|
14 |
+
img { max-width: 100%; vertical-align: middle; }
|
15 |
+
|
16 |
+
/** Figures */
|
17 |
+
figure > img { display: block; }
|
18 |
+
|
19 |
+
figcaption { font-size: 14px; }
|
20 |
+
|
21 |
+
/** Lists */
|
22 |
+
ul, ol { margin-left: 30px; }
|
23 |
+
|
24 |
+
li > ul, li > ol { margin-bottom: 0; }
|
25 |
+
|
26 |
+
/** Headings */
|
27 |
+
h1, h2, h3, h4, h5, h6 { font-weight: 400; }
|
28 |
+
|
29 |
+
/** Links */
|
30 |
+
a { color: #2a7ae2; text-decoration: none; }
|
31 |
+
a:visited { color: #1756a9; }
|
32 |
+
a:hover { color: #111; text-decoration: underline; }
|
33 |
+
.social-media-list a:hover { text-decoration: none; }
|
34 |
+
.social-media-list a:hover .username { text-decoration: underline; }
|
35 |
+
|
36 |
+
/** Blockquotes */
|
37 |
+
blockquote { color: #828282; border-left: 4px solid #e8e8e8; padding-left: 15px; font-size: 18px; letter-spacing: -1px; font-style: italic; }
|
38 |
+
blockquote > :last-child { margin-bottom: 0; }
|
39 |
+
|
40 |
+
/** Code formatting */
|
41 |
+
pre, code { font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; background-color: #eef; }
|
42 |
+
|
43 |
+
code { padding: 1px 5px; }
|
44 |
+
|
45 |
+
pre { padding: 8px 12px; overflow-x: auto; }
|
46 |
+
pre > code { border: 0; padding-right: 0; padding-left: 0; }
|
47 |
+
|
48 |
+
/** Wrapper */
|
49 |
+
.wrapper { max-width: -webkit-calc(800px - (30px * 2)); max-width: calc(800px - (30px * 2)); margin-right: auto; margin-left: auto; padding-right: 30px; padding-left: 30px; }
|
50 |
+
@media screen and (max-width: 800px) { .wrapper { max-width: -webkit-calc(800px - (30px)); max-width: calc(800px - (30px)); padding-right: 15px; padding-left: 15px; } }
|
51 |
+
|
52 |
+
/** Clearfix */
|
53 |
+
.wrapper:after, .footer-col-wrapper:after { content: ""; display: table; clear: both; }
|
54 |
+
|
55 |
+
/** Icons */
|
56 |
+
.svg-icon { width: 16px; height: 16px; display: inline-block; fill: #828282; padding-right: 5px; vertical-align: text-top; }
|
57 |
+
|
58 |
+
.social-media-list li + li { padding-top: 5px; }
|
59 |
+
|
60 |
+
/** Tables */
|
61 |
+
table { margin-bottom: 30px; width: 100%; text-align: left; color: #3f3f3f; border-collapse: collapse; border: 1px solid #e8e8e8; }
|
62 |
+
table tr:nth-child(even) { background-color: #f7f7f7; }
|
63 |
+
table th, table td { padding: 10px 15px; }
|
64 |
+
table th { background-color: #f0f0f0; border: 1px solid #dedede; border-bottom-color: #c9c9c9; }
|
65 |
+
table td { border: 1px solid #e8e8e8; }
|
66 |
+
|
67 |
+
/** Site header */
|
68 |
+
.site-header { border-top: 5px solid #424242; border-bottom: 1px solid #e8e8e8; min-height: 55.95px; position: relative; }
|
69 |
+
|
70 |
+
.site-title { font-size: 26px; font-weight: 300; line-height: 54px; letter-spacing: -1px; margin-bottom: 0; float: left; }
|
71 |
+
.site-title, .site-title:visited { color: #424242; }
|
72 |
+
|
73 |
+
.site-nav { float: right; line-height: 54px; }
|
74 |
+
.site-nav .nav-trigger { display: none; }
|
75 |
+
.site-nav .menu-icon { display: none; }
|
76 |
+
.site-nav .page-link { color: #111; line-height: 1.5; }
|
77 |
+
.site-nav .page-link:not(:last-child) { margin-right: 20px; }
|
78 |
+
@media screen and (max-width: 600px) { .site-nav { position: absolute; top: 9px; right: 15px; background-color: #fdfdfd; border: 1px solid #e8e8e8; border-radius: 5px; text-align: right; }
|
79 |
+
.site-nav label[for="nav-trigger"] { display: block; float: right; width: 36px; height: 36px; z-index: 2; cursor: pointer; }
|
80 |
+
.site-nav .menu-icon { display: block; float: right; width: 36px; height: 26px; line-height: 0; padding-top: 10px; text-align: center; }
|
81 |
+
.site-nav .menu-icon > svg { fill: #424242; }
|
82 |
+
.site-nav input ~ .trigger { clear: both; display: none; }
|
83 |
+
.site-nav input:checked ~ .trigger { display: block; padding-bottom: 5px; }
|
84 |
+
.site-nav .page-link { display: block; padding: 5px 10px; margin-left: 20px; }
|
85 |
+
.site-nav .page-link:not(:last-child) { margin-right: 0; } }
|
86 |
+
|
87 |
+
/** Site footer */
|
88 |
+
.site-footer { border-top: 1px solid #e8e8e8; padding: 30px 0; }
|
89 |
+
|
90 |
+
.footer-heading { font-size: 18px; margin-bottom: 15px; }
|
91 |
+
|
92 |
+
.contact-list, .social-media-list { list-style: none; margin-left: 0; }
|
93 |
+
|
94 |
+
.footer-col-wrapper { font-size: 15px; color: #828282; margin-left: -15px; }
|
95 |
+
|
96 |
+
.footer-col { float: left; margin-bottom: 15px; padding-left: 15px; }
|
97 |
+
|
98 |
+
.footer-col-1 { width: -webkit-calc(35% - (30px / 2)); width: calc(35% - (30px / 2)); }
|
99 |
+
|
100 |
+
.footer-col-2 { width: -webkit-calc(20% - (30px / 2)); width: calc(20% - (30px / 2)); }
|
101 |
+
|
102 |
+
.footer-col-3 { width: -webkit-calc(45% - (30px / 2)); width: calc(45% - (30px / 2)); }
|
103 |
+
|
104 |
+
@media screen and (max-width: 800px) { .footer-col-1, .footer-col-2 { width: -webkit-calc(50% - (30px / 2)); width: calc(50% - (30px / 2)); }
|
105 |
+
.footer-col-3 { width: -webkit-calc(100% - (30px / 2)); width: calc(100% - (30px / 2)); } }
|
106 |
+
@media screen and (max-width: 600px) { .footer-col { float: none; width: -webkit-calc(100% - (30px / 2)); width: calc(100% - (30px / 2)); } }
|
107 |
+
/** Page content */
|
108 |
+
.page-content { padding: 30px 0; flex: 1; }
|
109 |
+
|
110 |
+
.page-heading { font-size: 32px; }
|
111 |
+
|
112 |
+
.post-list-heading { font-size: 28px; }
|
113 |
+
|
114 |
+
.post-list { margin-left: 0; list-style: none; }
|
115 |
+
.post-list > li { margin-bottom: 30px; }
|
116 |
+
|
117 |
+
.post-meta { font-size: 14px; color: #828282; }
|
118 |
+
|
119 |
+
.post-link { display: block; font-size: 24px; }
|
120 |
+
|
121 |
+
/** Posts */
|
122 |
+
.post-header { margin-bottom: 30px; }
|
123 |
+
|
124 |
+
.post-title { font-size: 42px; letter-spacing: -1px; line-height: 1; }
|
125 |
+
@media screen and (max-width: 800px) { .post-title { font-size: 36px; } }
|
126 |
+
|
127 |
+
.post-content { margin-bottom: 30px; }
|
128 |
+
.post-content h2 { font-size: 32px; }
|
129 |
+
@media screen and (max-width: 800px) { .post-content h2 { font-size: 28px; } }
|
130 |
+
.post-content h3 { font-size: 26px; }
|
131 |
+
@media screen and (max-width: 800px) { .post-content h3 { font-size: 22px; } }
|
132 |
+
.post-content h4 { font-size: 20px; }
|
133 |
+
@media screen and (max-width: 800px) { .post-content h4 { font-size: 18px; } }
|
134 |
+
|
135 |
+
/** Syntax highlighting styles */
|
136 |
+
.highlight { background: #fff; }
|
137 |
+
.highlighter-rouge .highlight { background: #eef; }
|
138 |
+
.highlight .c { color: #998; font-style: italic; }
|
139 |
+
.highlight .err { color: #a61717; background-color: #e3d2d2; }
|
140 |
+
.highlight .k { font-weight: bold; }
|
141 |
+
.highlight .o { font-weight: bold; }
|
142 |
+
.highlight .cm { color: #998; font-style: italic; }
|
143 |
+
.highlight .cp { color: #999; font-weight: bold; }
|
144 |
+
.highlight .c1 { color: #998; font-style: italic; }
|
145 |
+
.highlight .cs { color: #999; font-weight: bold; font-style: italic; }
|
146 |
+
.highlight .gd { color: #000; background-color: #fdd; }
|
147 |
+
.highlight .gd .x { color: #000; background-color: #faa; }
|
148 |
+
.highlight .ge { font-style: italic; }
|
149 |
+
.highlight .gr { color: #a00; }
|
150 |
+
.highlight .gh { color: #999; }
|
151 |
+
.highlight .gi { color: #000; background-color: #dfd; }
|
152 |
+
.highlight .gi .x { color: #000; background-color: #afa; }
|
153 |
+
.highlight .go { color: #888; }
|
154 |
+
.highlight .gp { color: #555; }
|
155 |
+
.highlight .gs { font-weight: bold; }
|
156 |
+
.highlight .gu { color: #aaa; }
|
157 |
+
.highlight .gt { color: #a00; }
|
158 |
+
.highlight .kc { font-weight: bold; }
|
159 |
+
.highlight .kd { font-weight: bold; }
|
160 |
+
.highlight .kp { font-weight: bold; }
|
161 |
+
.highlight .kr { font-weight: bold; }
|
162 |
+
.highlight .kt { color: #458; font-weight: bold; }
|
163 |
+
.highlight .m { color: #099; }
|
164 |
+
.highlight .s { color: #d14; }
|
165 |
+
.highlight .na { color: #008080; }
|
166 |
+
.highlight .nb { color: #0086B3; }
|
167 |
+
.highlight .nc { color: #458; font-weight: bold; }
|
168 |
+
.highlight .no { color: #008080; }
|
169 |
+
.highlight .ni { color: #800080; }
|
170 |
+
.highlight .ne { color: #900; font-weight: bold; }
|
171 |
+
.highlight .nf { color: #900; font-weight: bold; }
|
172 |
+
.highlight .nn { color: #555; }
|
173 |
+
.highlight .nt { color: #000080; }
|
174 |
+
.highlight .nv { color: #008080; }
|
175 |
+
.highlight .ow { font-weight: bold; }
|
176 |
+
.highlight .w { color: #bbb; }
|
177 |
+
.highlight .mf { color: #099; }
|
178 |
+
.highlight .mh { color: #099; }
|
179 |
+
.highlight .mi { color: #099; }
|
180 |
+
.highlight .mo { color: #099; }
|
181 |
+
.highlight .sb { color: #d14; }
|
182 |
+
.highlight .sc { color: #d14; }
|
183 |
+
.highlight .sd { color: #d14; }
|
184 |
+
.highlight .s2 { color: #d14; }
|
185 |
+
.highlight .se { color: #d14; }
|
186 |
+
.highlight .sh { color: #d14; }
|
187 |
+
.highlight .si { color: #d14; }
|
188 |
+
.highlight .sx { color: #d14; }
|
189 |
+
.highlight .sr { color: #009926; }
|
190 |
+
.highlight .s1 { color: #d14; }
|
191 |
+
.highlight .ss { color: #990073; }
|
192 |
+
.highlight .bp { color: #999; }
|
193 |
+
.highlight .vc { color: #008080; }
|
194 |
+
.highlight .vg { color: #008080; }
|
195 |
+
.highlight .vi { color: #008080; }
|
196 |
+
.highlight .il { color: #099; }
|
_site/assets/minima-social-icons.svg
ADDED
|
_site/feed.xml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2021-10-19T11:58:07+02:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">Your awesome title</title><subtitle>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</subtitle><entry><title type="html">Welcome to Jekyll!</title><link href="http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html" rel="alternate" type="text/html" title="Welcome to Jekyll!" /><published>2021-10-19T09:57:57+02:00</published><updated>2021-10-19T09:57:57+02:00</updated><id>http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll</id><content type="html" xml:base="http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html"><p>You’ll find this post in your <code class="language-plaintext highlighter-rouge">_posts</code> directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run <code class="language-plaintext highlighter-rouge">jekyll serve</code>, which launches a web server and auto-regenerates your site when a file is updated.</p>
|
2 |
+
|
3 |
+
<p>Jekyll requires blog post files to be named according to the following format:</p>
|
4 |
+
|
5 |
+
<p><code class="language-plaintext highlighter-rouge">YEAR-MONTH-DAY-title.MARKUP</code></p>
|
6 |
+
|
7 |
+
<p>Where <code class="language-plaintext highlighter-rouge">YEAR</code> is a four-digit number, <code class="language-plaintext highlighter-rouge">MONTH</code> and <code class="language-plaintext highlighter-rouge">DAY</code> are both two-digit numbers, and <code class="language-plaintext highlighter-rouge">MARKUP</code> is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.</p>
|
8 |
+
|
9 |
+
<p>Jekyll also offers powerful support for code snippets:</p>
|
10 |
+
|
11 |
+
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">print_hi</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
|
12 |
+
<span class="nb">puts</span> <span class="s2">"Hi, </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">"</span>
|
13 |
+
<span class="k">end</span>
|
14 |
+
<span class="n">print_hi</span><span class="p">(</span><span class="s1">'Tom'</span><span class="p">)</span>
|
15 |
+
<span class="c1">#=&gt; prints 'Hi, Tom' to STDOUT.</span></code></pre></figure>
|
16 |
+
|
17 |
+
<p>Check out the <a href="https://jekyllrb.com/docs/home">Jekyll docs</a> for more info on how to get the most out of Jekyll. File all bugs/feature requests at <a href="https://github.com/jekyll/jekyll">Jekyll’s GitHub repo</a>. If you have questions, you can ask them on <a href="https://talk.jekyllrb.com/">Jekyll Talk</a>.</p></content><author><name></name></author><category term="jekyll" /><category term="update" /><summary type="html">You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated. Jekyll requires blog post files to be named according to the following format: YEAR-MONTH-DAY-title.MARKUP Where YEAR is a four-digit number, MONTH and DAY are both two-digit numbers, and MARKUP is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. Jekyll also offers powerful support for code snippets: def print_hi(name) puts "Hi, #{name}" end print_hi('Tom') #=&gt; prints 'Hi, Tom' to STDOUT. Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.</summary></entry></feed>
|
_site/index.html
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>Your awesome title | Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="Your awesome title" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
11 |
+
<meta property="og:description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta name="twitter:card" content="summary" />
|
16 |
+
<meta property="twitter:title" content="Your awesome title" />
|
17 |
+
<script type="application/ld+json">
|
18 |
+
{"@type":"WebSite","headline":"Your awesome title","url":"http://localhost:4000/","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","name":"Your awesome title","@context":"https://schema.org"}</script>
|
19 |
+
<!-- End Jekyll SEO tag -->
|
20 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
21 |
+
<body><header class="site-header" role="banner">
|
22 |
+
|
23 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
24 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
25 |
+
<label for="nav-trigger">
|
26 |
+
<span class="menu-icon">
|
27 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
28 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
29 |
+
</svg>
|
30 |
+
</span>
|
31 |
+
</label>
|
32 |
+
|
33 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
34 |
+
</nav></div>
|
35 |
+
</header>
|
36 |
+
<main class="page-content" aria-label="Content">
|
37 |
+
<div class="wrapper">
|
38 |
+
<div class="home">
|
39 |
+
<h2 class="post-list-heading">Posts</h2>
|
40 |
+
<ul class="post-list"><li><span class="post-meta">Oct 19, 2021</span>
|
41 |
+
<h3>
|
42 |
+
<a class="post-link" href="/jekyll/update/2021/10/19/welcome-to-jekyll.html">
|
43 |
+
Welcome to Jekyll!
|
44 |
+
</a>
|
45 |
+
</h3></li></ul>
|
46 |
+
|
47 |
+
<p class="rss-subscribe">subscribe <a href="/feed.xml">via RSS</a></p></div>
|
48 |
+
|
49 |
+
</div>
|
50 |
+
</main><footer class="site-footer h-card">
|
51 |
+
<data class="u-url" href="/"></data>
|
52 |
+
|
53 |
+
<div class="wrapper">
|
54 |
+
|
55 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
56 |
+
|
57 |
+
<div class="footer-col-wrapper">
|
58 |
+
<div class="footer-col footer-col-1">
|
59 |
+
<ul class="contact-list">
|
60 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
61 |
+
</div>
|
62 |
+
|
63 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
<div class="footer-col footer-col-3">
|
67 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
68 |
+
</div>
|
69 |
+
</div>
|
70 |
+
|
71 |
+
</div>
|
72 |
+
|
73 |
+
</footer>
|
74 |
+
</body>
|
75 |
+
|
76 |
+
</html>
|
_site/jekyll/update/2021/10/19/welcome-to-jekyll.html
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>Welcome to Jekyll! | Your awesome title</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="Welcome to Jekyll!" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated. Jekyll requires blog post files to be named according to the following format: YEAR-MONTH-DAY-title.MARKUP Where YEAR is a four-digit number, MONTH and DAY are both two-digit numbers, and MARKUP is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. Jekyll also offers powerful support for code snippets: def print_hi(name) puts "Hi, #{name}" end print_hi('Tom') #=> prints 'Hi, Tom' to STDOUT. Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk." />
|
11 |
+
<meta property="og:description" content="You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated. Jekyll requires blog post files to be named according to the following format: YEAR-MONTH-DAY-title.MARKUP Where YEAR is a four-digit number, MONTH and DAY are both two-digit numbers, and MARKUP is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. Jekyll also offers powerful support for code snippets: def print_hi(name) puts "Hi, #{name}" end print_hi('Tom') #=> prints 'Hi, Tom' to STDOUT. Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta property="og:type" content="article" />
|
16 |
+
<meta property="article:published_time" content="2021-10-19T09:57:57+02:00" />
|
17 |
+
<meta name="twitter:card" content="summary" />
|
18 |
+
<meta property="twitter:title" content="Welcome to Jekyll!" />
|
19 |
+
<script type="application/ld+json">
|
20 |
+
{"@type":"BlogPosting","headline":"Welcome to Jekyll!","dateModified":"2021-10-19T09:57:57+02:00","datePublished":"2021-10-19T09:57:57+02:00","url":"http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/jekyll/update/2021/10/19/welcome-to-jekyll.html"},"description":"You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated. Jekyll requires blog post files to be named according to the following format: YEAR-MONTH-DAY-title.MARKUP Where YEAR is a four-digit number, MONTH and DAY are both two-digit numbers, and MARKUP is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. Jekyll also offers powerful support for code snippets: def print_hi(name) puts "Hi, #{name}" end print_hi('Tom') #=> prints 'Hi, Tom' to STDOUT. Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.","@context":"https://schema.org"}</script>
|
21 |
+
<!-- End Jekyll SEO tag -->
|
22 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
23 |
+
<body><header class="site-header" role="banner">
|
24 |
+
|
25 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
26 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
27 |
+
<label for="nav-trigger">
|
28 |
+
<span class="menu-icon">
|
29 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
30 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
31 |
+
</svg>
|
32 |
+
</span>
|
33 |
+
</label>
|
34 |
+
|
35 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
36 |
+
</nav></div>
|
37 |
+
</header>
|
38 |
+
<main class="page-content" aria-label="Content">
|
39 |
+
<div class="wrapper">
|
40 |
+
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
41 |
+
|
42 |
+
<header class="post-header">
|
43 |
+
<h1 class="post-title p-name" itemprop="name headline">Welcome to Jekyll!</h1>
|
44 |
+
<p class="post-meta">
|
45 |
+
<time class="dt-published" datetime="2021-10-19T09:57:57+02:00" itemprop="datePublished">Oct 19, 2021
|
46 |
+
</time></p>
|
47 |
+
</header>
|
48 |
+
|
49 |
+
<div class="post-content e-content" itemprop="articleBody">
|
50 |
+
<p>You’ll find this post in your <code class="language-plaintext highlighter-rouge">_posts</code> directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run <code class="language-plaintext highlighter-rouge">jekyll serve</code>, which launches a web server and auto-regenerates your site when a file is updated.</p>
|
51 |
+
|
52 |
+
<p>Jekyll requires blog post files to be named according to the following format:</p>
|
53 |
+
|
54 |
+
<p><code class="language-plaintext highlighter-rouge">YEAR-MONTH-DAY-title.MARKUP</code></p>
|
55 |
+
|
56 |
+
<p>Where <code class="language-plaintext highlighter-rouge">YEAR</code> is a four-digit number, <code class="language-plaintext highlighter-rouge">MONTH</code> and <code class="language-plaintext highlighter-rouge">DAY</code> are both two-digit numbers, and <code class="language-plaintext highlighter-rouge">MARKUP</code> is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.</p>
|
57 |
+
|
58 |
+
<p>Jekyll also offers powerful support for code snippets:</p>
|
59 |
+
|
60 |
+
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">print_hi</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
|
61 |
+
<span class="nb">puts</span> <span class="s2">"Hi, </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">"</span>
|
62 |
+
<span class="k">end</span>
|
63 |
+
<span class="n">print_hi</span><span class="p">(</span><span class="s1">'Tom'</span><span class="p">)</span>
|
64 |
+
<span class="c1">#=> prints 'Hi, Tom' to STDOUT.</span></code></pre></figure>
|
65 |
+
|
66 |
+
<p>Check out the <a href="https://jekyllrb.com/docs/home">Jekyll docs</a> for more info on how to get the most out of Jekyll. File all bugs/feature requests at <a href="https://github.com/jekyll/jekyll">Jekyll’s GitHub repo</a>. If you have questions, you can ask them on <a href="https://talk.jekyllrb.com/">Jekyll Talk</a>.</p>
|
67 |
+
|
68 |
+
|
69 |
+
</div><a class="u-url" href="/jekyll/update/2021/10/19/welcome-to-jekyll.html" hidden></a>
|
70 |
+
</article>
|
71 |
+
|
72 |
+
</div>
|
73 |
+
</main><footer class="site-footer h-card">
|
74 |
+
<data class="u-url" href="/"></data>
|
75 |
+
|
76 |
+
<div class="wrapper">
|
77 |
+
|
78 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
79 |
+
|
80 |
+
<div class="footer-col-wrapper">
|
81 |
+
<div class="footer-col footer-col-1">
|
82 |
+
<ul class="contact-list">
|
83 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
84 |
+
</div>
|
85 |
+
|
86 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
87 |
+
</div>
|
88 |
+
|
89 |
+
<div class="footer-col footer-col-3">
|
90 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
91 |
+
</div>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
</div>
|
95 |
+
|
96 |
+
</footer>
|
97 |
+
</body>
|
98 |
+
|
99 |
+
</html>
|
_site/large-scale-demo/index.html
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>Large scale demo | Your awesome title</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="Large scale demo" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
11 |
+
<meta property="og:description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/large-scale-demo/" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/large-scale-demo/" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta name="twitter:card" content="summary" />
|
16 |
+
<meta property="twitter:title" content="Large scale demo" />
|
17 |
+
<script type="application/ld+json">
|
18 |
+
{"@type":"WebPage","headline":"Large scale demo","url":"http://localhost:4000/large-scale-demo/","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","@context":"https://schema.org"}</script>
|
19 |
+
<!-- End Jekyll SEO tag -->
|
20 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
21 |
+
<body><header class="site-header" role="banner">
|
22 |
+
|
23 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
24 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
25 |
+
<label for="nav-trigger">
|
26 |
+
<span class="menu-icon">
|
27 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
28 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
29 |
+
</svg>
|
30 |
+
</span>
|
31 |
+
</label>
|
32 |
+
|
33 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
34 |
+
</nav></div>
|
35 |
+
</header>
|
36 |
+
<main class="page-content" aria-label="Content">
|
37 |
+
<div class="wrapper">
|
38 |
+
<article class="post">
|
39 |
+
|
40 |
+
<header class="post-header">
|
41 |
+
<h1 class="post-title">Large scale demo</h1>
|
42 |
+
</header>
|
43 |
+
|
44 |
+
<div class="post-content">
|
45 |
+
|
46 |
+
|
47 |
+
</div>
|
48 |
+
|
49 |
+
</article>
|
50 |
+
|
51 |
+
</div>
|
52 |
+
</main><footer class="site-footer h-card">
|
53 |
+
<data class="u-url" href="/"></data>
|
54 |
+
|
55 |
+
<div class="wrapper">
|
56 |
+
|
57 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
58 |
+
|
59 |
+
<div class="footer-col-wrapper">
|
60 |
+
<div class="footer-col footer-col-1">
|
61 |
+
<ul class="contact-list">
|
62 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
63 |
+
</div>
|
64 |
+
|
65 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
66 |
+
</div>
|
67 |
+
|
68 |
+
<div class="footer-col footer-col-3">
|
69 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
+
|
73 |
+
</div>
|
74 |
+
|
75 |
+
</footer>
|
76 |
+
</body>
|
77 |
+
|
78 |
+
</html>
|
_site/main-training/index.html
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en"><head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.7.1 -->
|
6 |
+
<title>Main training | Your awesome title</title>
|
7 |
+
<meta name="generator" content="Jekyll v3.9.0" />
|
8 |
+
<meta property="og:title" content="Main training" />
|
9 |
+
<meta property="og:locale" content="en_US" />
|
10 |
+
<meta name="description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
11 |
+
<meta property="og:description" content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description." />
|
12 |
+
<link rel="canonical" href="http://localhost:4000/main-training/" />
|
13 |
+
<meta property="og:url" content="http://localhost:4000/main-training/" />
|
14 |
+
<meta property="og:site_name" content="Your awesome title" />
|
15 |
+
<meta name="twitter:card" content="summary" />
|
16 |
+
<meta property="twitter:title" content="Main training" />
|
17 |
+
<script type="application/ld+json">
|
18 |
+
{"@type":"WebPage","headline":"Main training","url":"http://localhost:4000/main-training/","description":"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.","@context":"https://schema.org"}</script>
|
19 |
+
<!-- End Jekyll SEO tag -->
|
20 |
+
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Your awesome title" /></head>
|
21 |
+
<body><header class="site-header" role="banner">
|
22 |
+
|
23 |
+
<div class="wrapper"><a class="site-title" rel="author" href="/">Your awesome title</a><nav class="site-nav">
|
24 |
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
25 |
+
<label for="nav-trigger">
|
26 |
+
<span class="menu-icon">
|
27 |
+
<svg viewBox="0 0 18 15" width="18px" height="15px">
|
28 |
+
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
|
29 |
+
</svg>
|
30 |
+
</span>
|
31 |
+
</label>
|
32 |
+
|
33 |
+
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/large-scale-demo/">Large scale demo</a><a class="page-link" href="/main-training/">Main training</a></div>
|
34 |
+
</nav></div>
|
35 |
+
</header>
|
36 |
+
<main class="page-content" aria-label="Content">
|
37 |
+
<div class="wrapper">
|
38 |
+
<article class="post">
|
39 |
+
|
40 |
+
<header class="post-header">
|
41 |
+
<h1 class="post-title">Main training</h1>
|
42 |
+
</header>
|
43 |
+
|
44 |
+
<div class="post-content">
|
45 |
+
|
46 |
+
|
47 |
+
</div>
|
48 |
+
|
49 |
+
</article>
|
50 |
+
|
51 |
+
</div>
|
52 |
+
</main><footer class="site-footer h-card">
|
53 |
+
<data class="u-url" href="/"></data>
|
54 |
+
|
55 |
+
<div class="wrapper">
|
56 |
+
|
57 |
+
<h2 class="footer-heading">Your awesome title</h2>
|
58 |
+
|
59 |
+
<div class="footer-col-wrapper">
|
60 |
+
<div class="footer-col footer-col-1">
|
61 |
+
<ul class="contact-list">
|
62 |
+
<li class="p-name">Your awesome title</li><li><a class="u-email" href="mailto:your-email@example.com">your-email@example.com</a></li></ul>
|
63 |
+
</div>
|
64 |
+
|
65 |
+
<div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/jekyll"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">jekyll</span></a></li><li><a href="https://www.twitter.com/jekyllrb"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">jekyllrb</span></a></li></ul>
|
66 |
+
</div>
|
67 |
+
|
68 |
+
<div class="footer-col footer-col-3">
|
69 |
+
<p>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</p>
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
+
|
73 |
+
</div>
|
74 |
+
|
75 |
+
</footer>
|
76 |
+
</body>
|
77 |
+
|
78 |
+
</html>
|
efficient_training.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
header-animate.js
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// draw background; Note: this background is based on https://codepen.io/pawelqcm/pen/oxPYox by Pawel
|
2 |
+
// Note 2: Pawel, you're awesome.
|
3 |
+
(function() {
|
4 |
+
var main_element = document.getElementById("header_main");
|
5 |
+
var content_element = document.getElementById("overlay");
|
6 |
+
var canvas = document.querySelector('canvas');
|
7 |
+
var title_elem = document.getElementsByClassName("title_elem")[0];
|
8 |
+
var title_text = document.getElementById("title_text");
|
9 |
+
ctx = canvas.getContext('2d');
|
10 |
+
if (!ctx)
|
11 |
+
console.warn("Your browser does not support canvas, content may be broken :'(");
|
12 |
+
|
13 |
+
var SENSITIVITY, SIBLINGS_LIMIT, DENSITY, TOTAL_NODES, ANCHOR_LENGTH, CURSOR_HEIGHT, CURSOR_WIDTH;
|
14 |
+
css_opts = getComputedStyle(document.documentElement);
|
15 |
+
SENSITIVITY = css_opts.getPropertyValue('--background-sensitivity') || 120;
|
16 |
+
SIBLINGS_LIMIT = css_opts.getPropertyValue('--background-siblings') || 7;
|
17 |
+
NODE_DENSITY = css_opts.getPropertyValue('--background-node-density') || 6;
|
18 |
+
CURSOR_WIDTH = css_opts.getPropertyValue('--background-cursor-width') || 250;
|
19 |
+
CURSOR_HEIGHT = css_opts.getPropertyValue('--background-cursor-height') || 250;
|
20 |
+
CURSOR_VERTICAL_SHRINK = css_opts.getPropertyValue('--background-cursor-vertical-shrink') || 0.1;
|
21 |
+
SPEED_COEF = css_opts.getPropertyValue('--background-speed') || 1;
|
22 |
+
ENERGY_DECAY = css_opts.getPropertyValue('--energy-decay') || 2;
|
23 |
+
SHOW_IF_WIDER_THAN = css_opts.getPropertyValue('--background-show-if-wider-than') || 500;
|
24 |
+
MOVE_ON_CURSOR = css_opts.getPropertyValue('--background-move-on-cursor').includes("true") || false;
|
25 |
+
|
26 |
+
var nodes = [];
|
27 |
+
choice = (choices => choices[Math.floor(Math.random() * choices.length)])
|
28 |
+
sample_color = () => choice([[40, 40, 40], [133, 133, 133]])
|
29 |
+
|
30 |
+
ANCHOR_LENGTH = 20;
|
31 |
+
|
32 |
+
var cursor = {x: 0, y: 0};
|
33 |
+
|
34 |
+
function centralize_cursor() {
|
35 |
+
var rect = document.getElementById("bug-logo").getBoundingClientRect()
|
36 |
+
var window_left = window.pageXOffset || document.documentElement.scrollLeft;
|
37 |
+
var window_top = window.pageYOffset || document.documentElement.scrollTop;
|
38 |
+
cursor.x = window_left + rect.left + rect.width / 2;
|
39 |
+
cursor.y = window_top + rect.top + rect.height / 2;
|
40 |
+
}
|
41 |
+
|
42 |
+
function Node(x, y) {
|
43 |
+
this.anchorX = x;
|
44 |
+
this.anchorY = y;
|
45 |
+
this.x = Math.random() * (x - (x - ANCHOR_LENGTH)) + (x - ANCHOR_LENGTH);
|
46 |
+
this.y = Math.random() * (y - (y - ANCHOR_LENGTH)) + (y - ANCHOR_LENGTH);
|
47 |
+
this.vx = (Math.random() * 2 - 1) * SPEED_COEF;
|
48 |
+
this.vy = (Math.random() * 2 - 1) * SPEED_COEF;
|
49 |
+
this.energy = Math.random() * 100;
|
50 |
+
this.radius = Math.random();
|
51 |
+
this.siblings = [];
|
52 |
+
[this.r, this.g, this.b] = sample_color()
|
53 |
+
this.brightness = 0;
|
54 |
+
}
|
55 |
+
|
56 |
+
Node.prototype.drawNode = function() {
|
57 |
+
var color = `rgba(${this.r}, ${this.g}, ${this.b}, ${this.brightness})`;
|
58 |
+
ctx.beginPath();
|
59 |
+
ctx.arc(this.x, this.y, 2 * this.radius + 2 * this.siblings.length / SIBLINGS_LIMIT, 0, 2 * Math.PI);
|
60 |
+
ctx.fillStyle = color;
|
61 |
+
ctx.fill();
|
62 |
+
};
|
63 |
+
|
64 |
+
Node.prototype.drawConnections = function() {
|
65 |
+
for (var i = 0; i < this.siblings.length; i++) {
|
66 |
+
var color = `rgba(133, 133, 133, ${this.brightness})`;
|
67 |
+
ctx.beginPath();
|
68 |
+
ctx.moveTo(this.x, this.y);
|
69 |
+
ctx.lineTo(this.siblings[i].x, this.siblings[i].y);
|
70 |
+
ctx.lineWidth = 1 - calcDistance(this, this.siblings[i]) / SENSITIVITY;
|
71 |
+
ctx.strokeStyle = color;
|
72 |
+
ctx.stroke();
|
73 |
+
}
|
74 |
+
};
|
75 |
+
|
76 |
+
|
77 |
+
Node.prototype.moveNode = function() {
|
78 |
+
this.energy -= ENERGY_DECAY;
|
79 |
+
if (this.energy < 1) {
|
80 |
+
this.energy = Math.random() * 100;
|
81 |
+
if (this.x - this.anchorX < -ANCHOR_LENGTH) {
|
82 |
+
this.vx = Math.random() * SPEED_COEF;
|
83 |
+
} else if (this.x - this.anchorX > ANCHOR_LENGTH) {
|
84 |
+
this.vx = Math.random() * -SPEED_COEF;
|
85 |
+
} else {
|
86 |
+
this.vx = Math.random() * SPEED_COEF * 2 - SPEED_COEF;
|
87 |
+
}
|
88 |
+
if (this.y - this.anchorY < -ANCHOR_LENGTH) {
|
89 |
+
this.vy = Math.random() * SPEED_COEF;
|
90 |
+
} else if (this.y - this.anchorY > ANCHOR_LENGTH) {
|
91 |
+
this.vy = Math.random() * -SPEED_COEF;
|
92 |
+
} else {
|
93 |
+
this.vy = Math.random() * SPEED_COEF * 2 - SPEED_COEF;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
relative_speed_rate = Math.min(canvas.height / 100, 10.0)
|
97 |
+
this.x += this.vx * this.energy * relative_speed_rate;
|
98 |
+
this.y += this.vy * this.energy * relative_speed_rate;
|
99 |
+
};
|
100 |
+
|
101 |
+
function initNodes() {
|
102 |
+
centralize_cursor();
|
103 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
104 |
+
if (canvas.width >= SHOW_IF_WIDER_THAN)
|
105 |
+
total_nodes = Math.round(NODE_DENSITY * (canvas.width / 100 * canvas.height / 100));
|
106 |
+
else
|
107 |
+
total_nodes = 0;
|
108 |
+
nodes = [];
|
109 |
+
for (var i = 0; i < total_nodes; i++)
|
110 |
+
nodes.push(new Node(50 + Math.random() * (canvas.width - 100),
|
111 |
+
5 + Math.random() * (canvas.height - 10)));
|
112 |
+
}
|
113 |
+
|
114 |
+
function calcDistance(node1, node2) {
|
115 |
+
return Math.sqrt(Math.pow(node1.x - node2.x, 2) + (Math.pow(node1.y - node2.y, 2)));
|
116 |
+
}
|
117 |
+
|
118 |
+
function findSiblings() {
|
119 |
+
var node1, node2, distance;
|
120 |
+
for (var i = 0; i < nodes.length; i++) {
|
121 |
+
node1 = nodes[i];
|
122 |
+
node1.siblings = [];
|
123 |
+
for (var j = 0; j < nodes.length; j++) {
|
124 |
+
node2 = nodes[j];
|
125 |
+
if (node1 !== node2) {
|
126 |
+
distance = calcDistance(node1, node2);
|
127 |
+
if (distance < SENSITIVITY) {
|
128 |
+
if (node1.siblings.length < SIBLINGS_LIMIT) {
|
129 |
+
node1.siblings.push(node2);
|
130 |
+
} else {
|
131 |
+
var node_sibling_distance = 0;
|
132 |
+
var max_distance = 0;
|
133 |
+
var s;
|
134 |
+
for (var k = 0; k < SIBLINGS_LIMIT; k++) {
|
135 |
+
node_sibling_distance = calcDistance(node1, node1.siblings[k]);
|
136 |
+
if (node_sibling_distance > max_distance) {
|
137 |
+
max_distance = node_sibling_distance;
|
138 |
+
s = k;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
if (distance < max_distance) {
|
142 |
+
node1.siblings.splice(s, 1);
|
143 |
+
node1.siblings.push(node2);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
function redrawScene() {
|
153 |
+
resizeWindow();
|
154 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
155 |
+
findSiblings();
|
156 |
+
var i, node, distance;
|
157 |
+
for (i = 0; i < nodes.length; i++) {
|
158 |
+
node = nodes[i];
|
159 |
+
scaled_distance = calcDistance({x: cursor.x / CURSOR_WIDTH, y: cursor.y / CURSOR_HEIGHT},
|
160 |
+
{x: node.x / CURSOR_WIDTH, y: node.y / CURSOR_HEIGHT});
|
161 |
+
|
162 |
+
node.brightness = Math.max(1 - scaled_distance, 0);
|
163 |
+
}
|
164 |
+
for (i = 0; i < nodes.length; i++) {
|
165 |
+
node = nodes[i];
|
166 |
+
if (node.brightness) {
|
167 |
+
node.drawConnections();
|
168 |
+
node.drawNode();
|
169 |
+
}
|
170 |
+
node.moveNode();
|
171 |
+
}
|
172 |
+
requestAnimationFrame(redrawScene);
|
173 |
+
}
|
174 |
+
|
175 |
+
function initHandlers() {
|
176 |
+
document.addEventListener('resize', resizeWindow);
|
177 |
+
document.addEventListener('orientationchange', resizeWindow);
|
178 |
+
if (MOVE_ON_CURSOR) {
|
179 |
+
document.addEventListener('mousemove', moveHandler);
|
180 |
+
document.addEventListener('touchmove', moveHandler);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
function resizeWindow(evt) {
|
185 |
+
var new_width, new_height;
|
186 |
+
new_width = Math.round(Math.max(title_elem.getBoundingClientRect().right, window.innerWidth))
|
187 |
+
if (screen.width < 640)
|
188 |
+
title_text.style.fontSize = "20px";
|
189 |
+
else
|
190 |
+
title_text.style.fontSize = "32px";
|
191 |
+
|
192 |
+
|
193 |
+
if (!MOVE_ON_CURSOR)
|
194 |
+
new_height = Math.round(title_elem.getBoundingClientRect().top - canvas.getBoundingClientRect().top);
|
195 |
+
else
|
196 |
+
new_height = Math.round(Math.max(
|
197 |
+
content_element.offsetHeight, content_element.scrollHeight,
|
198 |
+
content_element.clientHeight, window.innerHeight));
|
199 |
+
|
200 |
+
if (canvas.width != new_width || canvas.height != new_height) {
|
201 |
+
canvas.width = new_width;
|
202 |
+
canvas.height = new_height;
|
203 |
+
main_element.style.height = (title_elem.offsetHeight + title_elem.offsetTop + 10) + "px";
|
204 |
+
initNodes();
|
205 |
+
}
|
206 |
+
if (!MOVE_ON_CURSOR)
|
207 |
+
centralize_cursor();
|
208 |
+
}
|
209 |
+
|
210 |
+
function moveHandler(evt) {
|
211 |
+
if (evt.type == "mousemove") {
|
212 |
+
cursor.x = window.pageXOffset + evt.clientX;
|
213 |
+
cursor.y = window.pageYOffset + evt.clientY;
|
214 |
+
}
|
215 |
+
else { // touch event
|
216 |
+
cursor.x = window.pageXOffset + evt.changedTouches[0].clientX;
|
217 |
+
cursor.y = window.pageYOffset + evt.changedTouches[0].clientY;
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
initHandlers();
|
222 |
+
initNodes();
|
223 |
+
redrawScene();
|
224 |
+
|
225 |
+
})();
|
index.html
ADDED
@@ -0,0 +1,477 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<!doctype html>
|
3 |
+
<html lang="en">
|
4 |
+
<head>
|
5 |
+
<meta charset="utf-8">
|
6 |
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7 |
+
|
8 |
+
<title>Training Transformers Together</title>
|
9 |
+
<meta name="description" content="A NeurIPS'21 demonstration that explains how to train large models together with multiple collaborators.">
|
10 |
+
<link rel="mask-icon" href="https://learning-at-home.github.io/logo_small.png">
|
11 |
+
<link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://learning-at-home.github.io/logo.png">
|
12 |
+
<link rel="icon" class="js-site-favicon" type="image/png" href="https://learning-at-home.github.io/logo.png">
|
13 |
+
<meta property="og:url" content="https://training-transformers-together.github.io">
|
14 |
+
<meta property="og:site_name" content="Training Transformers Together">
|
15 |
+
<meta property="og:title" content="Train vast neural networks together">
|
16 |
+
<meta property="og:description" content="A NeurIPS'21 demonstration that explains how to train large models together with multiple collaborators.">
|
17 |
+
<meta property="og:image" content="https://learning-at-home.github.io/logo_small.png">
|
18 |
+
<meta property="og:image:type" content="image/png">
|
19 |
+
<meta property="og:image:width" content="96">
|
20 |
+
<meta property="og:image:height" content="96">
|
21 |
+
<meta property="twitter:site" content="https://training-transformers-together.github.io">
|
22 |
+
<meta property="twitter:creator" content="Yandex, Hugging Face, University of Washington, Hivemind team & contributors">
|
23 |
+
<meta property="twitter:card" content="summary_large_image">
|
24 |
+
<meta property="twitter:title" content="Training Transformers Together">
|
25 |
+
<meta property="twitter:description" content="A NeurIPS'21 demonstration that explains how to train large models together with multiple collaborators.">
|
26 |
+
<meta property="twitter:image:src" content="https://learning-at-home.github.io/logo_horizontal.png">
|
27 |
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
28 |
+
|
29 |
+
<!-- Bootstrap core CSS -->
|
30 |
+
<link href="https://bootswatch.com/5/flatly/bootstrap.css" rel="stylesheet">
|
31 |
+
|
32 |
+
<!-- Custom styles for this template -->
|
33 |
+
<link href="./style.css" rel="stylesheet">
|
34 |
+
</head>
|
35 |
+
|
36 |
+
<body>
|
37 |
+
<div id="header_main" style="display: block;" class="mb-0 pb-0">
|
38 |
+
<canvas></canvas>
|
39 |
+
<div id="overlay">
|
40 |
+
<div id="header_window">
|
41 |
+
<div id="header">
|
42 |
+
<img src="https://learning-at-home.github.io/logo.png" id="bug-logo"
|
43 |
+
style="width: 40%; max-height: 320px; max-width: 320px; z-index:1000; position: relative;">
|
44 |
+
<br>
|
45 |
+
<h1 class="faded title title_elem mb-1 pb-1" style="margin-top:-25px; margin-bottom:-10px">
|
46 |
+
<p style="margin-top: 0px; font-weight:bolder; margin-bottom:0px;">
|
47 |
+
<span id="title_text">Training Transformers Together</span>
|
48 |
+
</p>
|
49 |
+
<p style="font-size: 18px; margin-top:0px; margin-bottom:5px;">
|
50 |
+
large-scale deep learning for everyone, by everyone</p>
|
51 |
+
<p style="font-size: 18px; font-weight:lighter; margin-top:0px; margin-bottom:0px;">
|
52 |
+
A NeurIPS 2021 Demonstration</p>
|
53 |
+
</h1>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
<script src="./header-animate.js"></script>
|
59 |
+
|
60 |
+
<div class="container d-flex justify-content-center mb-2 pb-2" style="max-width: 500px">
|
61 |
+
<div class="row text-center align-items-center justify-content-center">
|
62 |
+
<div class="col-3">
|
63 |
+
<a href="https://research.yandex.com/">
|
64 |
+
<img src="logos/yandex.png" class="img-fluid center-block" style="max-width: 66%" alt="Yandex Research">
|
65 |
+
</a>
|
66 |
+
</div>
|
67 |
+
<div class="col-3 px-2">
|
68 |
+
<a href="https://huggingface.co/">
|
69 |
+
<img src="logos/huggingface.png" class="img-fluid center-block" style="max-width: 66%" alt="Hugging Face">
|
70 |
+
</a>
|
71 |
+
</div>
|
72 |
+
<div class="col-3 px-3">
|
73 |
+
<a href="https://www.hse.ru/en/">
|
74 |
+
<img src="logos/hse.png" class="img-fluid center-block" style="max-width: 66%" alt="HSE University">
|
75 |
+
</a>
|
76 |
+
</div>
|
77 |
+
<div class="col-3 px-2">
|
78 |
+
<a href="http://www.washington.edu/">
|
79 |
+
<img src="logos/uwash.png" class="img-fluid center-block" alt="University of Washington">
|
80 |
+
</a>
|
81 |
+
</div>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
|
85 |
+
<div class="container" style="display: block;">
|
86 |
+
<p>
|
87 |
+
There was a time when you could comfortably train state-of-the-art vision and language models at home on your workstation.
|
88 |
+
The first convolutional neural net to beat ImageNet
|
89 |
+
(<a target="_blank" href="https://proceedings.neurips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf">AlexNet</a>)
|
90 |
+
was trained for 5-6 days on two gamer-grade GPUs. In contrast, today's Top-1 ImageNet model
|
91 |
+
(<a target="_blank" href="https://arxiv.org/abs/2106.04803">CoAtNet</a>)
|
92 |
+
takes 20,000 TPU-v3 days. And things are even worse in the NLP world: training
|
93 |
+
<a target="_blank" href="https://arxiv.org/abs/2005.14165">GPT‑3</a>
|
94 |
+
on a top-tier server with 8x A100 would take decades.
|
95 |
+
</p>
|
96 |
+
<p>
|
97 |
+
So, can individual researchers and small labs still train state-of-the-art models? Yes we can!
|
98 |
+
All it takes is for a bunch of us to come together. In fact, we're doing it right now and <b>you are invited to join!</b>
|
99 |
+
</p>
|
100 |
+
<iframe id="iframe_main" src="https://hf.space/streamlitiframe/training-transformers-together/dashboard-embedded/+"
|
101 |
+
data-src="https://hf.space/streamlitiframe/training-transformers-together/dashboard-embedded/+"
|
102 |
+
data-sdk="streamlit"
|
103 |
+
title="Streamlit app" class="container p-0 flex-grow space-iframe"
|
104 |
+
allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking"
|
105 |
+
sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"
|
106 |
+
style="top:-200px; left:0; bottom:0; right:0; width:100%; height:200px; border:none; margin:0; padding:0; z-index:999999;" scrolling=no>
|
107 |
+
<p>This was meant to be an IFrame, but your browser did not display it.</p>
|
108 |
+
<p>Please go to <a href="https://huggingface.co/spaces/training-transformers-together/demo">https://huggingface.co/spaces/training-transformers-together/demo</a>.</p>
|
109 |
+
</iframe>
|
110 |
+
<p>
|
111 |
+
In this demo, we train a model similar to <a target="_blank" href="https://openai.com/blog/dall-e/">OpenAI DALL-E</a> —
|
112 |
+
a Transformer model that generates images from text descriptions.
|
113 |
+
It is trained on <a target="_blank" href="https://laion.ai/laion-400-open-dataset/">LAION-400M</a>,
|
114 |
+
the world's largest openly available image-text-pair dataset with 400 million samples. Our model is based on
|
115 |
+
the <a target="_blank" href="https://github.com/lucidrains/DALLE-pytorch">dalle‑pytorch</a> implementation
|
116 |
+
by <a target="_blank" href="https://github.com/lucidrains">Phil Wang</a> with a few tweaks to make it communication-efficient.
|
117 |
+
</p>
|
118 |
+
<div class="accordion" id="accordionExample">
|
119 |
+
<div class="accordion-item">
|
120 |
+
<h2 class="accordion-header" id="headingOne">
|
121 |
+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
|
122 |
+
How to train efficiently over the Internet?
|
123 |
+
</button>
|
124 |
+
</h2>
|
125 |
+
<div id="collapseOne" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
|
126 |
+
<div class="accordion-body">
|
127 |
+
<p>
|
128 |
+
Modern distributed training algorithms are designed for HPC clusters with a 10-100 gigabit per second bandwidth.
|
129 |
+
In turn, a typical Internet connection runs at 10-100 megabits per second: that’s three orders of magnitude slower.
|
130 |
+
To make distributed training efficient, you need to win back these three orders of magnitude.
|
131 |
+
This may seem daunting at first, but in reality, DL researchers have already made all the necessary pieces for solving this puzzle:
|
132 |
+
</p>
|
133 |
+
<table class="table table-hover">
|
134 |
+
<thead>
|
135 |
+
<tr>
|
136 |
+
<th scope="col">Speed‑up</th>
|
137 |
+
<th scope="col">How to achieve</th>
|
138 |
+
</tr>
|
139 |
+
</thead>
|
140 |
+
<tbody>
|
141 |
+
<tr><td class="centered"><strong>4-16x</strong></td><td>
|
142 |
+
<strong>Large-batch training:</strong> <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/1904.00962">You et al. (2019)</a> proposed a way for training neural networks efficiently with larger batches, and hence, fewer communication rounds.
|
143 |
+
</td></tr>
|
144 |
+
<tr><td class="centered"><strong>4-32x</strong></td><td>
|
145 |
+
<strong>Gradient compression:</strong> from simple <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/1511.04561">8-bit quantization</a>
|
146 |
+
to advanced techniques such as <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/1712.01887">Deep Gradient Compression</a>,
|
147 |
+
<a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/1905.13727">PowerSGD</a>, <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2102.02888">1-bit Adam</a>,
|
148 |
+
and many others. As a rule of thumb, these techniques can safely reduce communication by 16-32x. More extreme compression is often
|
149 |
+
possible, but it may affect stability or final quality.
|
150 |
+
</td></tr>
|
151 |
+
<tr><td class="centered"><strong>4-24x</strong></td><td>
|
152 |
+
<strong>Parameter sharing:</strong> reusing parameters between model layers results in a model with fewer parameters,
|
153 |
+
and hence, fewer gradients to communicate. <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/1909.11942">Lan et al. (2019)</a> and
|
154 |
+
<a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/pdf/2107.11817.pdf">Xue et al. (2021)</a> propose efficient parameter sharing architectures
|
155 |
+
for NLP and computer vision.
|
156 |
+
</td></tr>
|
157 |
+
<tr><td class="centered"><strong>1.5-2x</strong></td><td>
|
158 |
+
<strong>Overlapping computation with communication:</strong> running network communication in background while
|
159 |
+
computing the next portion of gradients. This is a <a target="_blank" rel="noopener noreferrer" href="https://ur.booksc.eu/book/1624068/2d0506">long-standing trick from HPC</a>
|
160 |
+
that was recently adapted for DL training. <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2101.06840">Ren et al. (2021)</a> show that
|
161 |
+
updating parameters in background while computing the next batch of gradients does not harm convergence.
|
162 |
+
</td></tr>
|
163 |
+
</tbody>
|
164 |
+
</table>
|
165 |
+
<p>
|
166 |
+
These techniques are already more than enough to cover 1000x slower communication.
|
167 |
+
This means that in practice you can pick and choose which of them you want in your training run.
|
168 |
+
For this demo, we use 8x larger batches, 4x compression, 12x parameter sharing and partial overlapping.
|
169 |
+
If you don’t want parameter sharing, you can trade it for more advanced gradient compression or larger batches.
|
170 |
+
</p>
|
171 |
+
</div>
|
172 |
+
</div>
|
173 |
+
</div>
|
174 |
+
</div>
|
175 |
+
<div class="accordion" id="accordionAnother" style="margin-top: 10px;">
|
176 |
+
<div class="accordion-item">
|
177 |
+
<h2 class="accordion-header" id="headingTwo">
|
178 |
+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseOne">
|
179 |
+
How to train with different device types?
|
180 |
+
</button>
|
181 |
+
</h2>
|
182 |
+
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionAnother">
|
183 |
+
<div class="accordion-body">
|
184 |
+
<p>
|
185 |
+
Most distributed DL frameworks assume that the computation is performed by a fleet of identical devices,
|
186 |
+
typically GPU servers or TPU cores. Under this assumption, each device can be assigned an equal part of
|
187 |
+
computation, such as processing a fixed batch size of training samples.
|
188 |
+
However, this quickly breaks down if workers use different device types. If one participant uses a GPU (e.g. P100)
|
189 |
+
and another runs on TPU-v2-8, it is difficult to find a regime where both devices will be fully utilized.
|
190 |
+
</p>
|
191 |
+
<p>
|
192 |
+
To make the best use of all available devices, we let each device accumulate gradients at its own pace
|
193 |
+
with individually tuned batch size and some other features (e.g. gradient checkpointing or using XLA).
|
194 |
+
Once workers collectively aggregate some predefined global batch size, they average their gradients
|
195 |
+
with weights proportional to each worker's individual contribution (i.e. number of samples processed).
|
196 |
+
</p>
|
197 |
+
<a class="block overflow-hidden">
|
198 |
+
<div class="w-full h-40 mb-2 bg-gray-900 group-hover:bg-gray-850 rounded-lg flex items-start justify-start overflow-hidden">
|
199 |
+
<iframe src="https://www.youtube.com/embed/zdVsg5zsGdc" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0"
|
200 |
+
style="width: 100%; height: 240px"></iframe>
|
201 |
+
</div>
|
202 |
+
</a>
|
203 |
+
<p>
|
204 |
+
This technique allows the "swarm" to automatically adjust its behavior as peers join, leave or fail.
|
205 |
+
For instance, if several high-performance peers join the experiment, other peers will need to process a smaller
|
206 |
+
number of samples per optimizer step, and hence, the collaboration will train faster with the same hyperparameters.
|
207 |
+
In turn, if one of the workers fails and loses its progress (e.g. due to a fp16 overflow), others will make
|
208 |
+
up for that by processing slightly more. For more details on how this works, please refer to
|
209 |
+
<a target="_blank" rel="noopener noreferrer" href="https://papers.nips.cc/paper/2021/hash/41a60377ba920919939d83326ebee5a1-Abstract.html">
|
210 |
+
"Deep Learning In Open Collaborations"</a> paper or the corresponding <a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/blog/collaborative-training">blog post</a>.
|
211 |
+
</p>
|
212 |
+
</div>
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
</div>
|
216 |
+
|
217 |
+
|
218 |
+
<h3 class="my-4">How do I join?</h3>
|
219 |
+
|
220 |
+
<p>This section will be updated <strong>on December 7</strong>.</p>
|
221 |
+
|
222 |
+
<h3 class="my-4">Practical aspects</h3>
|
223 |
+
|
224 |
+
<div class="border-bottom pb-3">
|
225 |
+
<!-- Nav tabs -->
|
226 |
+
<ul class="nav nav-tabs m-3">
|
227 |
+
<li class="nav-item">
|
228 |
+
<a class="nav-link active" data-bs-toggle="tab" href="#memory-efficiency">Memory-Efficient Training</a>
|
229 |
+
</li>
|
230 |
+
<li class="nav-item">
|
231 |
+
<a class="nav-link" data-bs-toggle="tab" href="#security">Security</a>
|
232 |
+
</li>
|
233 |
+
<li class="nav-item">
|
234 |
+
<a class="nav-link" data-bs-toggle="tab" href="#make-your-own">Make Your Own</a>
|
235 |
+
</li>
|
236 |
+
</ul>
|
237 |
+
|
238 |
+
<!-- Tab panes -->
|
239 |
+
<div class="tab-content">
|
240 |
+
<div class="tab-pane fade active show" id="memory-efficiency">
|
241 |
+
<p>
|
242 |
+
Our aim is to train a large model in a decentralized fashion on consumer hardware or low-end cloud instances.
|
243 |
+
This means we need to make the model, dataset, and other memory buffers fit onto a few GB of disk, 12-16 GB of CPU RAM,
|
244 |
+
and 8-12 GB of GPU memory. Unfortunately, this rules out many popular techniques such as
|
245 |
+
<a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2101.06840">ZeRO-Offload</a>:
|
246 |
+
there is simply not enough RAM for that. Instead, we must make better use of what limited memory we have.
|
247 |
+
To do this, we use two techniques: 8-bit Optimizers for GPU memory and dataset streaming for RAM & HDD.
|
248 |
+
</p>
|
249 |
+
<p>
|
250 |
+
<b>8-bit optimizers:</b>
|
251 |
+
Using optimizers such as LAMB or Adam requires four times as much GPU memory as simply storing model parameters (8 bytes vs 2 bytes)
|
252 |
+
because of additional gradient statistics.
|
253 |
+
As such, for training large models with many parameters, the optimizer state takes the largest amount of memory.
|
254 |
+
With 8-bit optimizers, this amount is reduced by 75% (2 bytes), making it much easier to fit large models onto consumer GPUs.
|
255 |
+
</p><p>
|
256 |
+
Naturally, we can combine this technique with offloading and store 8-bit optimizer states in the CPU memory rather
|
257 |
+
than in the GPU memory (0 bytes GPU, 2 bytes CPU). To perform an optimizer update, we transfer the GPU gradients
|
258 |
+
to the CPU, update the model parameters, and then copy the new weights to the GPU.
|
259 |
+
We can do this for each weight one-by-one so that the additional CPU memory required for the
|
260 |
+
optimizer update is minimal.
|
261 |
+
This combination of offloading and 8-bit optimizers means that we conserve GPU memory (0 bytes per parameter)
|
262 |
+
and also use only a limited amount of CPU memory (2 bytes per parameter).
|
263 |
+
|
264 |
+
</p>
|
265 |
+
<p>
|
266 |
+
<b>Dataset streaming:</b>
|
267 |
+
Usually data is stored on disk and needs to be fully or partially loaded into RAM for training.
|
268 |
+
Large datasets used for pretraining measure in <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2101.00027">hundreds of gigabytes</a>
|
269 |
+
or even <a target="_blank" rel="noopener noreferrer" href="https://laion.ai/laion-400-open-dataset/">terabytes</a>.
|
270 |
+
This can pose a significant problem, as most desktop and cheap cloud instances simply do not have that much free space.
|
271 |
+
Furthermore, downloading the data over the Internet would take up hours before one can even begin training.
|
272 |
+
</p>
|
273 |
+
<center>
|
274 |
+
<img src="./logos/stream.gif" id="stream"
|
275 |
+
style="width: 80%; max-height: 200px; max-width: 640px; z-index:1000; top:-10px; position: relative;">
|
276 |
+
</center>
|
277 |
+
<p>
|
278 |
+
To circumvent these problems, it is possible to stream the data in the same way as you stream online videos.
|
279 |
+
Participants download a small random portion of the training dataset and immediately begin training on it,
|
280 |
+
while additional data is loaded in the background. As such, we can train a model with virtually no storage
|
281 |
+
overhead from the dataset, and switching to a new dataset is as simple as changing an argument of the dataset class.
|
282 |
+
</p>
|
283 |
+
<h5><b>Here's our tutorial covering these methods:</b>
|
284 |
+
<a target="_blank" rel="noopener noreferrer" href="https://colab.research.google.com/gist/justheuristic/75f6a2a731f05a213a55cd2c8a458aaf/fine-tune-a-language-model-with-dataset-streaming-and-8-bit-optimizers.ipynb">
|
285 |
+
<span>
|
286 |
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" width="150px">
|
287 |
+
</span>
|
288 |
+
</a></h5>
|
289 |
+
|
290 |
+
</div>
|
291 |
+
<div class="tab-pane fade" id="security">
|
292 |
+
<p>In this section, we discuss common concerns related to security of collaborative training:</p>
|
293 |
+
|
294 |
+
<p>
|
295 |
+
<b>Q: If I join a collaborative experiment, do I allow other people to execute code on my computer?</b>
|
296 |
+
</p>
|
297 |
+
|
298 |
+
<p>
|
299 |
+
<b>A:</b> During the training, participants only exchange data (gradients, statistics, model weights) and never send code to each other.
|
300 |
+
No other peer can execute arbitrary code on your computer.
|
301 |
+
</p>
|
302 |
+
|
303 |
+
<p>
|
304 |
+
To join the experiment, you typically need to run the code (implementing the model, data streaming, training loop, etc.)
|
305 |
+
from a repository or a Colab notebook provided by the authors of the experiment.
|
306 |
+
This is no different from running any other open source project/Colab notebook.
|
307 |
+
</p>
|
308 |
+
|
309 |
+
<p>
|
310 |
+
<b>Q: Can a malicious participant influence the training outcome?</b>
|
311 |
+
</p>
|
312 |
+
|
313 |
+
<p>
|
314 |
+
<b>A:</b> It is indeed possible unless we use some defense mechanisms.
|
315 |
+
For instance, a malicious participant can damage model weights by sending large numbers instead of correct gradients.
|
316 |
+
The same can happen due to broken hardware or misconfiguration.
|
317 |
+
</p>
|
318 |
+
|
319 |
+
<ul>
|
320 |
+
<li>
|
321 |
+
<p>
|
322 |
+
One possible defense is using <b>authentication</b> combined with <b>model checkpointing</b>.
|
323 |
+
In this case, participants should log in (e.g. with their Hugging Face account) to interact with the rest of the collaboration.
|
324 |
+
In turn, moderators can screen potential participants and add them to an allowlist.
|
325 |
+
If something goes wrong (e.g. a participant sends invalid gradients and the model diverges),
|
326 |
+
the moderators remove them from the list and revert the model to the latest checkpoint unaffected by the attack.
|
327 |
+
</p>
|
328 |
+
|
329 |
+
<!-- <p><b>Spoiler (TODO): How to implement authentication in a decentralized system efficiently?</b></p>-->
|
330 |
+
|
331 |
+
<p>
|
332 |
+
Nice bonus: using this data, the moderators can acknowledge the personal contribution of each participant.
|
333 |
+
</p>
|
334 |
+
</li>
|
335 |
+
<li>
|
336 |
+
<p>
|
337 |
+
Another defense is replacing the naive averaging of the peers' gradients with an <b>aggregation technique that is robust to outliers</b>.
|
338 |
+
<a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2012.10333">Karimireddy et al. (2020)</a>
|
339 |
+
suggested such a technique (named CenteredClip) and proved that it does not significantly affect the model's convergence.
|
340 |
+
</p>
|
341 |
+
|
342 |
+
<!-- <p><b>Spoiler (TODO): How does CenteredClip protect from outliers? (Interactive Demo)</b></p>-->
|
343 |
+
|
344 |
+
<p>
|
345 |
+
In our case, CenteredClip is useful but not enough to protect from malicious participants,
|
346 |
+
since it implies that the CenteredClip procedure itself is performed by a trusted server.
|
347 |
+
By contrast, in our decentralized system, all participants can aggregate a part of the gradients,
|
348 |
+
and we cannot assume any of them to be trusted.
|
349 |
+
</p>
|
350 |
+
|
351 |
+
<p>
|
352 |
+
Recently, <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2106.11257">Gorbunov et al. (2021)</a>
|
353 |
+
proposed a robust aggregation protocol for decentralized systems that does not require this assumption.
|
354 |
+
This protocol uses CenteredClip as a subroutine but is able to detect and ban participants who performed it incorrectly.
|
355 |
+
</p>
|
356 |
+
</li>
|
357 |
+
</ul>
|
358 |
+
</div>
|
359 |
+
<div class="tab-pane fade" id="make-your-own">
|
360 |
+
<p>In this section, we provide a recipe for you to run a collaborative training experiment yourself.</p>
|
361 |
+
<p>
|
362 |
+
<b>Got confused?</b> Feel free to ask any questions in our <a target="_blank" rel="noopener noreferrer" href="https://discord.gg/uGugx9zYvN">Discord</a>!
|
363 |
+
</p>
|
364 |
+
<ol>
|
365 |
+
<li class="mb-2">
|
366 |
+
Set up dataset streaming:
|
367 |
+
<ul>
|
368 |
+
<li>
|
369 |
+
<a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/docs/datasets/share_dataset.html">Upload</a> your dataset to the Hugging Face Hub
|
370 |
+
in a streaming-friendly format (<a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/datasets/laion/laion_100m_vqgan_f8">example</a>).
|
371 |
+
</li>
|
372 |
+
<li>Set up dataset streaming (see the "Memory-Efficient Training" section).</li>
|
373 |
+
</ul>
|
374 |
+
</li>
|
375 |
+
<li class="mb-2">
|
376 |
+
Write the code of training peers (<a target="_blank" rel="noopener noreferrer" href="https://github.com/learning-at-home/dalle-hivemind/blob/main/run_trainer.py">example</a>):
|
377 |
+
<ul>
|
378 |
+
<li>Implement your model, set up dataset streaming, and write the training loop.</li>
|
379 |
+
<li>
|
380 |
+
Get familiar with the <a href="https://github.com/learning-at-home/hivemind">hivemind</a> library
|
381 |
+
(<a target="_blank" rel="noopener noreferrer" href="https://learning-at-home.readthedocs.io/en/latest/user/quickstart.html">quickstart</a>).
|
382 |
+
</li>
|
383 |
+
<li>
|
384 |
+
In the training loop, wrap up your PyTorch optimizer with
|
385 |
+
<a target="_blank" rel="noopener noreferrer" href="https://learning-at-home.readthedocs.io/en/latest/modules/optim.html#hivemind.optim.experimental.optimizer.Optimizer">hivemind.Optimizer</a>
|
386 |
+
(<a target="_blank" rel="noopener noreferrer" href="https://github.com/learning-at-home/dalle-hivemind/blob/main/task.py#L121">example</a>).
|
387 |
+
</li>
|
388 |
+
</ul>
|
389 |
+
</li>
|
390 |
+
<li class="mb-2">
|
391 |
+
<b>(optional)</b> Write the code of auxiliary peers (<a target="_blank" rel="noopener noreferrer" href="https://github.com/learning-at-home/dalle-hivemind/blob/main/run_aux_peer.py">example</a>):
|
392 |
+
<ul>
|
393 |
+
<li>
|
394 |
+
Auxiliary peers are a special kind of peers responsible for
|
395 |
+
logging experiment progress (e.g., to <a target="_blank" rel="noopener noreferrer" href="https://wandb.ai/">Weights & Biases</a>)
|
396 |
+
and uploading model checkpoints (e.g., to <a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/docs/transformers/model_sharing">Hugging Face Hub</a>).
|
397 |
+
</li>
|
398 |
+
<li>
|
399 |
+
Such peers don't need to calculate gradients and may be launched on cheap machines without GPUs.
|
400 |
+
</li>
|
401 |
+
<li>
|
402 |
+
They can serve as a convenient entry point to
|
403 |
+
<a href="https://learning-at-home.readthedocs.io/en/latest/modules/dht.html">hivemind.DHT</a>
|
404 |
+
(i.e., their address can be specified as <code>initial_peers</code>).
|
405 |
+
</li>
|
406 |
+
<li>
|
407 |
+
It is useful to fix their address by providing <code>host_maddrs</code> and <code>identity_path</code>
|
408 |
+
arguments to <code>hivemind.DHT</code>
|
409 |
+
(these are forwarded to the underlying <a target="_blank" rel="noopener noreferrer" href="https://libp2p.io/">libp2p</a> daemon).
|
410 |
+
</li>
|
411 |
+
</ul>
|
412 |
+
</li>
|
413 |
+
<li class="mb-2">
|
414 |
+
<b>(optional)</b> Make it easier for other people to join:
|
415 |
+
<!-- To be discussed: What about "Make it easier and safer for other people to join" as there is the authentication bullet point?-->
|
416 |
+
<ul>
|
417 |
+
<li>
|
418 |
+
Create notebooks for free GPU providers (Google Colab, Kaggle, AWS SageMaker, etc.).
|
419 |
+
People may run them online and/or download and run them on their own hardware.
|
420 |
+
</li>
|
421 |
+
<li>
|
422 |
+
<a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/organizations/new">Create</a> a Hugging Face organization
|
423 |
+
with all resources related to the training
|
424 |
+
(dataset, model, inference demo, how-to-join walkthrough, links to a dashboard with loss and other metrics, etc.).
|
425 |
+
Look at <a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/training-transformers-together">ours</a> for an example.
|
426 |
+
</li>
|
427 |
+
<li>
|
428 |
+
Set up an authentication system (see the "Security" section).
|
429 |
+
For example, you can ask people to join your organization with their Hugging Face accounts
|
430 |
+
(the website allows either sharing a link for joining or manually approving new participants).
|
431 |
+
This allows you to screen the peers,
|
432 |
+
acknowledge their contributions (e.g., make a leaderboard), and
|
433 |
+
ban accounts who behave maliciously. You can use our <a href="https://collaborative-training-auth.huggingface.co/docs">authentication system</a> or deploy your own
|
434 |
+
(our <a href="https://github.com/huggingface/collaborative-training-auth/tree/demo-neurips">server implementation</a> might be a good start).
|
435 |
+
</li>
|
436 |
+
<li>
|
437 |
+
Set up an inference demo for your model (e.g., using <a target="_blank" rel="noopener noreferrer" href="https://huggingface.co/spaces">Spaces</a>) or
|
438 |
+
a script that periodically uploads the inference results to show the training progress.
|
439 |
+
</li>
|
440 |
+
</ul>
|
441 |
+
</li>
|
442 |
+
</ol>
|
443 |
+
</div>
|
444 |
+
</div>
|
445 |
+
|
446 |
+
</div>
|
447 |
+
|
448 |
+
<h3 class="my-3">Organizers</h3>
|
449 |
+
|
450 |
+
This demonstration was created by
|
451 |
+
<a href="https://twitter.com/sasha_borzunov">Alexander Borzunov*</a>,
|
452 |
+
<a href="https://twitter.com/m_ryabinin">Max Ryabinin*</a>,
|
453 |
+
<a href="https://twitter.com/Tim_Dettmers">Tim Dettmers*</a>,
|
454 |
+
<a href="https://twitter.com/qlhoest">Quentin Lhoest*</a>,
|
455 |
+
<a href="https://twitter.com/LucileSaulnier">Lucile Saulnier*</a>,
|
456 |
+
<a href="https://twitter.com/michael_diskin">Michael Diskin</a>,
|
457 |
+
<a href="https://twitter.com/YJernite">Yacine Jernite</a>, and
|
458 |
+
<a href="https://twitter.com/Thom_Wolf">Thomas Wolf</a>.
|
459 |
+
|
460 |
+
<h3 class="my-3">Learn more</h3>
|
461 |
+
|
462 |
+
<ul class="mb-5">
|
463 |
+
<li>A NeurIPS 2021 <a href="https://arxiv.org/abs/2106.10207">paper</a> on collaborative deep learning.</li>
|
464 |
+
<li><a href="https://github.com/learning-at-home/hivemind">hivemind</a> is a PyTorch library for decentralized deep learning.</li>
|
465 |
+
<li><a href="https://github.com/huggingface/datasets">🤗 Datasets</a> allows uploading and streaming training data from the Hub.</li>
|
466 |
+
<li><a href="https://github.com/facebookresearch/bitsandbytes">bitsandbytes</a> contains implementations of 8-bit optimizers.</li>
|
467 |
+
<li>A <a href="https://arxiv.org/abs/2110.02861">paper</a> on blockwise quantization for communication-efficient training.</li>
|
468 |
+
<!-- To be discussed: How about mentioning the blog post containing videos that explain SahajBERT's collaborative training? -->
|
469 |
+
<!-- <li>A <a href="https://hf.co/blog/collaborative-training">blog post</a> (with videos) on a collaborative training of a LM with 40 volunteers .</li> -->
|
470 |
+
</ul>
|
471 |
+
|
472 |
+
<!-- Bootstrap core JavaScript
|
473 |
+
================================================== -->
|
474 |
+
<!-- Placed at the end of the document so the pages load faster -->
|
475 |
+
<script src="https://getbootstrap.com/docs/5.0/dist/js/bootstrap.min.js"></script>
|
476 |
+
</body>
|
477 |
+
</html>
|
join-main-training.md
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
layout: page
|
3 |
+
title: "Join main training"
|
4 |
+
permalink: /join-main-training/
|
5 |
+
---
|
logos/hse.png
ADDED
![]() |
logos/huggingface.png
ADDED
![]() |
logos/stream.gif
ADDED
![]() |
logos/uwash.png
ADDED
![]() |
logos/yandex.png
ADDED
![]() |
quantization/quant.py
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Quantization reduces a bit representation to less bits for efficient storage or computation.
|
2 |
+
# Most floating point data types have a mapping from a bit representation, e.g. 0010 = 2 to a floating
|
3 |
+
# point representation 2 -> 2 / max(0010) = 2/15 = 0.133333
|
4 |
+
# As such, we can represent a floating point quantization a mapping from integers to floating point values, e.g.
|
5 |
+
# [0, 1, 2, 3] -> [-1.0, -0.25, 0.25 , 1.0]
|
6 |
+
import numpy as np
|
7 |
+
from scipy.spatial.distance import cdist
|
8 |
+
|
9 |
+
index = np.array([0, 1, 2, 3, 4, 5, 6, 7])
|
10 |
+
values = np.linspace(-1.0, 1.0, 8) # 3-bit linear quantization
|
11 |
+
print('quantization values:', values)
|
12 |
+
|
13 |
+
# To quantize an input distribution we first need to normalize its range into the range of the quantization values, in this case [-1.0, 1.0]
|
14 |
+
# We can do this through division by the abolute maximum value if our distribution is roughly symmetric (most distribution in deep learning are noramlly distributed)
|
15 |
+
|
16 |
+
rand_inputs = np.random.randn(1024, 1024).astype(np.float32)
|
17 |
+
|
18 |
+
absmax = np.max(np.abs(rand_inputs))
|
19 |
+
normed = rand_inputs / absmax
|
20 |
+
print('normalized min and max range', np.min(normed), np.max(normed))
|
21 |
+
|
22 |
+
# The next step is to round the input value to the closest quantization value.
|
23 |
+
# This can be done by performing a binary search of each element of the normalized input tensor with respect to the sorted values array:
|
24 |
+
# In this case, we simply compute the distance between all values and find the closest directly.
|
25 |
+
|
26 |
+
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1))
|
27 |
+
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape)
|
28 |
+
|
29 |
+
val, count = np.unique(closest_idx, return_counts=True)
|
30 |
+
print('Values:', val)
|
31 |
+
print('Count:', count)
|
32 |
+
|
33 |
+
# Closest index now represents the quantized 3 bit representation (4 different values). We can use this representation to store the data efficiently.
|
34 |
+
|
35 |
+
|
36 |
+
# ==================DEQUANTIZATION========================
|
37 |
+
# To dequantize the tensor we reverse the operations the we did
|
38 |
+
# 1. lookup the values corresponding to the 3-bit index
|
39 |
+
# 2. Denormalize by multipying by absmax
|
40 |
+
|
41 |
+
dequant = values[closest_idx]*absmax
|
42 |
+
# mean absolute error:
|
43 |
+
error = np.abs(dequant-rand_inputs).mean()
|
44 |
+
print(f'Absolute linear 3-bit quantization error: {error:.4f}')
|
45 |
+
|
46 |
+
# This yields an error of about 0.34 per value. We can do better with non-linear quantization.
|
47 |
+
|
48 |
+
# ==================NON-LINEAR QUANTIZATION========================
|
49 |
+
# In non-linear quantization the distance between quantization values is not always equal.
|
50 |
+
# This allows us to allocate more values to regions of high density. For example, the normal distribution has many values around 0.
|
51 |
+
# This can reduce the overall error in the distribution.
|
52 |
+
index = np.array([0, 1, 2, 3, 4, 5, 6, 7])
|
53 |
+
values = np.array([-1.0, -0.5, -0.25, -0.075, 0.075, 0.25, 0.5, 1.0])
|
54 |
+
|
55 |
+
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1))
|
56 |
+
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape)
|
57 |
+
|
58 |
+
val, count = np.unique(closest_idx, return_counts=True)
|
59 |
+
print('Values:', val)
|
60 |
+
print('Count:', count)
|
61 |
+
|
62 |
+
dequant = values[closest_idx]*absmax
|
63 |
+
error = np.abs(dequant-rand_inputs).mean()
|
64 |
+
print(f'Absolute non-linear 3-bit quantization error: {error:.4f}')
|
65 |
+
|
66 |
+
# dynamic quantization
|
67 |
+
# Adaptive from: https://github.com/facebookresearch/bitsandbytes/blob/main/bitsandbytes/functional.py
|
68 |
+
def create_dynamic_map(signed=True, n=7):
|
69 |
+
'''
|
70 |
+
Creates the dynamic quantiztion map.
|
71 |
+
The dynamic data type is made up of a dynamic exponent and
|
72 |
+
fraction. As the exponent increase from 0 to -7 the number
|
73 |
+
of bits available for the fraction shrinks.
|
74 |
+
This is a generalization of the dynamic type where a certain
|
75 |
+
number of the bits and be reserved for the linear quantization
|
76 |
+
region (the fraction). n determines the maximum number of
|
77 |
+
exponent bits.
|
78 |
+
For more details see
|
79 |
+
(8-Bit Approximations for Parallelism in Deep Learning)[https://arxiv.org/abs/1511.04561]
|
80 |
+
'''
|
81 |
+
|
82 |
+
data = []
|
83 |
+
# these are additional items that come from the case
|
84 |
+
# where all the exponent bits are zero and no
|
85 |
+
# indicator bit is present
|
86 |
+
additional_items = 2**(7-n)-1
|
87 |
+
if not signed: additional_items = 2*additional_items
|
88 |
+
for i in range(n):
|
89 |
+
fraction_items = 2**(i+7-n)+1 if signed else 2**(i+7-n+1)+1
|
90 |
+
boundaries = np.linspace(0.1, 1, fraction_items)
|
91 |
+
means = (boundaries[:-1]+boundaries[1:])/2.0
|
92 |
+
data += ((10**(-(n-1)+i))*means).tolist()
|
93 |
+
if signed:
|
94 |
+
data += (-(10**(-(n-1)+i))*means).tolist()
|
95 |
+
|
96 |
+
if additional_items > 0:
|
97 |
+
boundaries = np.linspace(0.1, 1, additional_items+1)
|
98 |
+
means = (boundaries[:-1]+boundaries[1:])/2.0
|
99 |
+
data += ((10**(-(n-1)+i))*means).tolist()
|
100 |
+
if signed:
|
101 |
+
data += (-(10**(-(n-1)+i))*means).tolist()
|
102 |
+
|
103 |
+
data.append(0)
|
104 |
+
data.append(1.0)
|
105 |
+
data.sort()
|
106 |
+
return np.array(data)
|
107 |
+
|
108 |
+
import time
|
109 |
+
|
110 |
+
values = create_dynamic_map(signed=True)
|
111 |
+
|
112 |
+
t0 = time.time()
|
113 |
+
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1))
|
114 |
+
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape)
|
115 |
+
quant_time = time.time()-t0
|
116 |
+
|
117 |
+
dequant = values[closest_idx]*absmax
|
118 |
+
error = np.abs(dequant-rand_inputs).mean()
|
119 |
+
print(f'Absolute dynamic 8-bit quantization error: {error:.4f}')
|
120 |
+
print(f'Total time taken: {quant_time:.4f} seconds.')
|
121 |
+
|
122 |
+
# This yields an error as low as 0.012. We could do even better when we use block-wise quantization.
|
123 |
+
# But performing block-wise quantization without optimized code is a bit slow. We can use the bitsandbytes library to do this quickly.
|
124 |
+
|
125 |
+
import torch
|
126 |
+
import bitsandbytes.functional as F
|
127 |
+
|
128 |
+
rand_inputs = torch.from_numpy(rand_inputs)
|
129 |
+
t0 = time.time()
|
130 |
+
quant_values, quant_state = F.quantize_blockwise(rand_inputs)
|
131 |
+
quant_time = time.time()-t0
|
132 |
+
dequant_values = F.dequantize_blockwise(quant_values, quant_state)
|
133 |
+
|
134 |
+
error = torch.abs(dequant_values-rand_inputs).mean().item()
|
135 |
+
print(f'Absolute dynamic block-wise 8-bit quantization error: {error:.4f}')
|
136 |
+
print(f'Total time taken (CPU): {quant_time:.4f} seconds.')
|
137 |
+
|
138 |
+
rand_inputs = rand_inputs.cuda()
|
139 |
+
t0 = time.time()
|
140 |
+
quant_values, quant_state = F.quantize_blockwise(rand_inputs)
|
141 |
+
quant_time = time.time()-t0
|
142 |
+
print(f'Total time taken (GPU): {quant_time:.4f} seconds.')
|
143 |
+
|
144 |
+
|
style.css
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
:root {
|
2 |
+
--border-color: black;
|
3 |
+
--window-color: white;
|
4 |
+
--background-move-on-cursor: false;
|
5 |
+
--background-color: white;
|
6 |
+
--background-cursor-width: 400;
|
7 |
+
--background-cursor-height: 200;
|
8 |
+
--background-show-if-wider-than: 500;
|
9 |
+
--background-speed: 0.001;
|
10 |
+
--energy-decay: 0.3;
|
11 |
+
}
|
12 |
+
html {
|
13 |
+
font-size: 14px;
|
14 |
+
}
|
15 |
+
@media (min-width: 768px) {
|
16 |
+
html {
|
17 |
+
font-size: 16px;
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
body {
|
22 |
+
width: 100%;
|
23 |
+
margin: 0 auto;
|
24 |
+
background-color: var(--background-color);
|
25 |
+
}
|
26 |
+
#header_main {
|
27 |
+
position: relative;
|
28 |
+
width: 100%;
|
29 |
+
margin: 0 auto;
|
30 |
+
}
|
31 |
+
#header_main canvas, #overlay {
|
32 |
+
width: 100%;
|
33 |
+
margin: 0 auto;
|
34 |
+
position: absolute;
|
35 |
+
}
|
36 |
+
|
37 |
+
a {
|
38 |
+
text-decoration: none;
|
39 |
+
}
|
40 |
+
|
41 |
+
a:hover {
|
42 |
+
text-decoration: underline;
|
43 |
+
}
|
44 |
+
|
45 |
+
.container {
|
46 |
+
max-width: 46rem;
|
47 |
+
}
|
48 |
+
|
49 |
+
.pricing-header {
|
50 |
+
max-width: 700px;
|
51 |
+
}
|
52 |
+
|
53 |
+
.card-deck .card {
|
54 |
+
min-width: 220px;
|
55 |
+
}
|
56 |
+
|
57 |
+
.border-top { border-top: 1px solid #e5e5e5; }
|
58 |
+
.border-bottom { border-bottom: 1px solid #e5e5e5; }
|
59 |
+
|
60 |
+
.box-shadow { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); }
|
61 |
+
|
62 |
+
.arxiv_button {
|
63 |
+
position: relative;
|
64 |
+
display: inline-block;
|
65 |
+
width: 78px;
|
66 |
+
height: 28px;
|
67 |
+
background-image: linear-gradient(180deg, #fafbfc, #eff3f6 90%);
|
68 |
+
color: #24292e;
|
69 |
+
border: 1px solid rgba(27,31,35,.2);
|
70 |
+
text-align: center;
|
71 |
+
cursor: pointer;
|
72 |
+
border-radius: 4px;
|
73 |
+
padding-right: 0px;
|
74 |
+
padding-top: 2.5px;
|
75 |
+
font-size: 12px;
|
76 |
+
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;
|
77 |
+
font-weight: 600;
|
78 |
+
}
|
79 |
+
.arxiv_button:before {
|
80 |
+
content: "";
|
81 |
+
vertical-align:middle;
|
82 |
+
display: inline-block;
|
83 |
+
width: 24px;
|
84 |
+
height: 24px;
|
85 |
+
border: none;
|
86 |
+
margin-left: -16px;
|
87 |
+
margin-right: 0px;
|
88 |
+
margin-top: -2px;
|
89 |
+
background: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" class="ionicon s-ion-icon" viewBox="0 0 512 512"><path d="M428 224H288a48 48 0 01-48-48V36a4 4 0 00-4-4h-92a64 64 0 00-64 64v320a64 64 0 0064 64h224a64 64 0 0064-64V228a4 4 0 00-4-4z"></path><path d="M419.22 188.59L275.41 44.78a2 2 0 00-3.41 1.41V176a16 16 0 0016 16h129.81a2 2 0 001.41-3.41z"></path></svg>') right center no-repeat;
|
90 |
+
background-size: 18px 16px;
|
91 |
+
}
|
92 |
+
.arxiv_button:hover {
|
93 |
+
background-color:#e6ebf1;
|
94 |
+
background-position:-0.5em;
|
95 |
+
border-color: #9fa4a9;
|
96 |
+
border-color:rgba(27,31,35,.35);
|
97 |
+
background-image:linear-gradient(180deg, #f0f3f6, #e6ebf1 90%)
|
98 |
+
}
|
99 |
+
|
100 |
+
#header_window {
|
101 |
+
width: 80%;
|
102 |
+
min-width: 320px;
|
103 |
+
margin: 0 auto;
|
104 |
+
text-align: center;
|
105 |
+
}
|
106 |
+
.faded {
|
107 |
+
margin: 0 auto;
|
108 |
+
background: var(--window-color);
|
109 |
+
box-shadow: 0 0 5px 5px var(--window-color);
|
110 |
+
font-family: cursive;
|
111 |
+
font-family: "Gill Sans", sans-serif;
|
112 |
+
display: inline-block
|
113 |
+
}
|
114 |
+
.padded {
|
115 |
+
width: 100%;
|
116 |
+
max-width: 800px;
|
117 |
+
text-align: left;
|
118 |
+
}
|
119 |
+
.title {
|
120 |
+
font-size: 32px;
|
121 |
+
box-shadow: 0 0 5px 5px var(--window-color);
|
122 |
+
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,
|
123 |
+
sans-serif,Apple Color Emoji,Segoe UI Emoji;
|
124 |
+
}
|
125 |
+
canvas {
|
126 |
+
background-color: var(--background-color);
|
127 |
+
width: 0px; /* will be changed on init */
|
128 |
+
overflow: hidden;
|
129 |
+
}
|
130 |
+
|
131 |
+
a {
|
132 |
+
color: #337ab7;
|
133 |
+
font-weight: 600;
|
134 |
+
}
|
135 |
+
a:hover {
|
136 |
+
color: #0056b3;
|
137 |
+
}
|
138 |
+
.nav-link {
|
139 |
+
color: #337ab7;
|
140 |
+
padding: 0.5rem 1rem;
|
141 |
+
font-weight: normal;
|
142 |
+
}
|
143 |
+
.nav-link:hover {
|
144 |
+
color: #337ab7;
|
145 |
+
}
|