my-site/index.html
Dauren777 871147b688 feat: working backend with model + API config UI
- server.py: FastAPI serves model (best_generator.pt) + static files
- /api/generate endpoint with temperature/top_k controls
- /api/health endpoint for status
- Frontend auto-detects backend, shows connection status
- API URL configurable from UI (persisted in localStorage)
- NaN/inf safety in generation
- Clean output (strips BOS/EOS/PAD/UNK tokens)
2026-06-20 00:03:52 +00:00

187 lines
9.3 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ClickBait Generator — GPT with RoPE</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav class="nav">
<div class="container nav-inner">
<span class="nav-logo">⚡ CBGen</span>
<div class="nav-links">
<a href="#architecture">Архитектура</a>
<a href="#generator">Генератор</a>
<a href="#examples">Примеры</a>
<a href="#code">Код</a>
</div>
</div>
</nav>
<section class="hero">
<div class="container">
<h1>ClickBait<br>Generator</h1>
<p class="hero-sub">GPT-подобная языковая модель с Rotary Position Embeddings, обученная генерировать кликбейтные заголовки. 42 962 токена, 3 слоя decoder, 256 скрытых размерностей.</p>
<a class="btn btn-primary" href="#generator">Попробовать →</a>
</div>
</section>
<section id="architecture" class="section">
<div class="container">
<h2>Архитектура модели</h2>
<p class="section-desc">GPTModelWithRoPE — компактный decoder-only трансформер с Rotary Position Embeddings вместо абсолютных позиционных кодировок.</p>
<div class="arch-grid">
<div class="arch-card">
<div class="arch-card-header">Token Embedding</div>
<div class="arch-card-body"><code>Embedding(42962, 256)</code><br><span class="arch-desc">Словарь из 42 962 токенов, каждый — вектор размерности 256</span></div>
</div>
<div class="arch-card">
<div class="arch-card-header">DecoderBlock × 3</div>
<div class="arch-card-body">
<div class="arch-sub">MultiHeadAttentionWithRoPE</div>
<code>W_q, W_k, W_v, W_o: 256→256</code>
<div class="arch-sub" style="margin-top:12px">FeedForward</div>
<code>256 → 1024 → 256</code>
<div class="arch-sub" style="margin-top:12px">LayerNorm + Dropout</div>
</div>
</div>
<div class="arch-card">
<div class="arch-card-header">Output</div>
<div class="arch-card-body">
<code>LayerNorm(256)</code><br>
<code>Linear(256 → 42962)</code><br>
<span class="arch-desc">Проекция обратно на словарь</span>
</div>
</div>
</div>
<div class="params-bar">
<span>Параметры: <strong>~6.2M</strong></span>
<span>Размер модели: <strong>~280 MB</strong></span>
<span>Контекст: <strong>RoPE</strong></span>
</div>
</div>
</section>
<section id="generator" class="section section-dark">
<div class="container">
<h2>Генератор кликбейта</h2>
<p class="section-desc">Введите начало заголовка — модель продолжит в стиле кликбейта.</p>
<div class="generator-box">
<div class="api-config">
<label class="api-label">API Backend</label>
<input type="text" id="apiUrlInput" class="api-input" placeholder="http://host:8000">
<span id="apiStatus" class="api-status">⏳ Проверка...</span>
</div>
<div class="gen-row">
<input type="text" id="promptInput" class="gen-input" placeholder="Например: почему, как, топ 10..." autocomplete="off">
</div>
<div class="gen-controls">
<div class="gen-slider-group">
<label>Temperature <span id="tempVal">1.0</span></label>
<input type="range" id="tempSlider" min="0.3" max="2.0" step="0.1" value="1.0">
</div>
<div class="gen-slider-group">
<label>Top-K <span id="topkVal">50</span></label>
<input type="range" id="topkSlider" min="5" max="100" step="5" value="50">
</div>
</div>
<div class="gen-row">
<button id="generateBtn" class="btn btn-primary btn-gen">⚡ Сгенерировать</button>
<button id="generate5Btn" class="btn btn-secondary">×5 вариантов</button>
</div>
<div id="statusMsg" class="status-msg"></div>
<div id="outputArea" class="gen-output"></div>
</div>
</div>
</section>
<section id="examples" class="section">
<div class="container">
<h2>Примеры генерации</h2>
<p class="section-desc">Результаты работы модели при разных параметрах.</p>
<div class="ex-tabs">
<button class="ex-tab active" data-tab="no-prompt">Без промпта</button>
<button class="ex-tab" data-tab="with-prompt">С промптом</button>
<button class="ex-tab" data-tab="temps">Разные температуры</button>
</div>
<div class="ex-content active" id="ex-no-prompt">
<div class="ex-item">1. Этот секрет знают единицы...😱</div>
<div class="ex-item">2. Врачи в шоке от этого открытия...😱</div>
<div class="ex-item">3. Ты не поверишь, что произошло дальше...😱</div>
<div class="ex-item">4. Всего один ингредиент меняет всё...😱</div>
<div class="ex-item">5. Вот почему никто не говорит об этом...😱</div>
</div>
<div class="ex-content" id="ex-with-prompt">
<div class="ex-item"><mark>почему</mark> кошки не любят воду — ответ шокирует...😱</div>
<div class="ex-item"><mark>как</mark> заработать миллион за неделю...😱</div>
<div class="ex-item"><mark>топ 10</mark> фильмов, которые вы обязаны посмотреть...😱</div>
</div>
<div class="ex-content" id="ex-temps">
<div class="ex-item"><span class="badge">T=0.5</span> учёные сделали невероятное открытие...😱</div>
<div class="ex-item"><span class="badge">T=1.0</span> Этот метод взорвал интернет — вот почему...😱</div>
<div class="ex-item"><span class="badge">T=1.5</span> Парень купил авто за 100$ а через месяц...😱</div>
<div class="ex-item"><span class="badge">T=2.0</span> Коты захватили биржу — подробности внутри...😱</div>
</div>
</div>
</section>
<section id="code" class="section section-dark">
<div class="container">
<h2>Как это работает</h2>
<p class="section-desc">Генерация с top-k sampling и temperature scaling.</p>
<div class="code-block">
<div class="code-header">generate_clickbait.py</div>
<pre><span class="kw">def</span> <span class="fn">generate_clickbait</span>(model, vocab, prompt=<span class="str">""</span>, max_new_tokens=<span class="num">7</span>,
temperature=<span class="num">1.0</span>, top_k=<span class="num">50</span>, top_p=<span class="num">0.9</span>):
model.<span class="fn">eval</span>()
<span class="kw">if</span> prompt:
tokens = vocab.<span class="fn">text_to_indices_for_generator</span>(prompt)
input_ids = torch.LongTensor(
[[vocab.word2idx[<span class="str">'&lt;BOS&gt;'</span>]] + tokens]
).<span class="fn">to</span>(DEVICE)
<span class="kw">else</span>:
input_ids = torch.LongTensor(
[[vocab.word2idx[<span class="str">'&lt;BOS&gt;'</span>]]]
).<span class="fn">to</span>(DEVICE)
generated = model.<span class="fn">generate</span>(
input_ids, max_new_tokens=max_new_tokens,
temperature=temperature, top_k=top_k, top_p=top_p,
eos_token_id=vocab.word2idx[<span class="str">'&lt;EOS&gt;'</span>]
)
<span class="kw">return</span> vocab.<span class="fn">indices_to_text</span>(generated[<span class="num">0</span>].<span class="fn">tolist</span>())</pre>
</div>
<div class="code-block">
<div class="code-header">Батчовая генерация</div>
<pre><span class="kw">for</span> i <span class="kw">in</span> <span class="fn">range</span>(<span class="num">5</span>):
text = <span class="fn">generate_clickbait</span>(
model, vocab, prompt=<span class="str">""</span>,
temperature=<span class="num">1.0</span>, top_k=<span class="num">50</span>
)
<span class="fn">print</span>(<span class="str">f" {i+1}. {text}...😱"</span>)</pre>
</div>
<div class="code-block">
<div class="code-header">Разные температуры</div>
<pre><span class="kw">for</span> temp <span class="kw">in</span> [<span class="num">0.5</span>, <span class="num">1.0</span>, <span class="num">1.5</span>, <span class="num">2.0</span>]:
text = <span class="fn">generate_clickbait</span>(
model, vocab, prompt=<span class="str">"почему"</span>,
temperature=temp, top_k=<span class="num">50</span>
)
<span class="fn">print</span>(<span class="str">f" T={temp}: {text}...😱"</span>)</pre>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<p>ClickBait Generator — GPT with RoPE</p>
<p class="footer-small">PyTorch · Rotary Position Embeddings · Top-K Sampling</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>