Text Generator Dashboard
สร้าง Django dashboard สำหรับสร้างข้อความด้วย Language Model
1. ข้อกำหนดโครงงาน
2. โครงสร้าง Django project
3. สิ่งที่ต้องทำใน ml/train.py
4. หน้า landing page
5. วิธีรันและตรวจสอบ
6. การส่งงาน
- โมเดล: Character-level หรือ Word-level language model ด้วย PyTorch
- ข้อมูล: ใช้ข้อความภาษาไทยหรืออังกฤษ (เช่น นิยาย, บทความ, บทเพลง)
- Architecture: RNN, LSTM, หรือ GRU (เลือกได้)
- Dashboard: SSE streaming แสดง training loss + generated text แบบ real-time
- หน้า landing: แสดง รหัสนักศึกษา และ ชื่อ-นามสกุล (hardcoded)
[สำคัญ] ใช้ Django + PyTorch เท่านั้น ห้ามใช้ Hugging Face transformers
# ผลลัพธ์ที่คาดหวัง: 1. เริ่ม server แล้วเห็นหน้า landing page ที่มีรหัสนักศึกษาและชื่อ-นามสกุล 2. กดปุ่ม "เริ่มฝึกสอน" แล้วเห็น - ค่า loss ลดลงแบบ real-time - ข้อความที่สร้างขึ้นอัปเดตทุก epoch 3. หลังฝึกสอนเสร็จ แสดงผลลัพธ์ - ตัวอย่างข้อความที่สร้าง (samples.txt) - Training loss curve 4. หน้า landing page แสดงรหัสและชื่อ ของนักศึกษาที่ทำโครงงาน
DL69/wk13/
├── pyproject.toml # uv project, Python 3.13
├── manage.py
├── mysite/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── dashboard/
│ ├── __init__.py
│ ├── apps.py
│ ├── views.py # SSE streaming endpoint
│ ├── urls.py # / → index, /train/ → SSE
│ ├── ml/
│ │ ├── __init__.py
│ │ └── train.py # ★ นักศึกษาเขียนโค้ดตรงนี้
│ ├── templates/
│ │ └── dashboard/
│ │ └── index.html # ★ ใส่รหัสและชื่อตรงนี้
│ └── static/
│ └── dashboard/
│ └── (ผลลัพธ์จาก train.py)
└── data/
└── corpus.txt # ข้อความสำหรับฝึกสอน
- pyproject.toml: กำหนด dependencies สำหรับ uv sync
- dashboard/ml/train.py: ไฟล์หลักที่นักศึกษาต้องเขียน
- dashboard/templates/dashboard/index.html: หน้า landing page
- data/corpus.txt: ไฟล์ข้อความสำหรับฝึกสอน
[สำคัญ] ห้ามลบหรือแก้ไขไฟล์ที่ไม่ได้ระบุว่าต้องแก้ — ใช้ไฟล์เดิมที่ให้มา
def train(on_progress=None):
"""
on_progress(epoch, loss, sample_text) → เรียกทุก epoch
"""
import torch
import torch.nn as nn
# 1. โหลดข้อความ
# text = open('data/corpus.txt').read()
# 2. สร้าง vocabulary
# chars = sorted(set(text))
# char_to_idx = {c: i for i, c in enumerate(chars)}
# 3. สร้าง training sequences
# seq_length = 100
# X[i] = text[i:i+seq_length]
# y[i] = text[i+1:i+seq_length+1]
# 4. สร้างโมเดล LSTM
class TextGenerator(nn.Module):
def __init__(self, vocab_size, embed_dim=64, hidden=128):
super().__init__()
self.embed = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden, batch_first=True)
self.fc = nn.Linear(hidden, vocab_size)
def forward(self, x):
out = self.embed(x)
out, _ = self.lstm(out)
return self.fc(out[:, -1, :])
# 5. Training loop
for epoch in range(num_epochs):
# forward, loss, backward, step
# ทุก 10 epoch: generate sample text
# เรียก on_progress(epoch, loss, sample)
pass
# 6. บันทึกผลลัพธ์
# - samples.txt (ตัวอย่างข้อความ)
# - loss_curve.png
- ข้อ 1: โหลดข้อความแล้วสร้าง vocabulary
- ข้อ 2: สร้าง training sequences ด้วย sliding window
- ข้อ 3: สร้าง LSTM model พร้อม embedding layer
- ข้อ 4: Training loop + generate sample text ทุก 10 epoch
- ข้อ 5: บันทึก samples.txt และ loss_curve.png
[เคล็ดลับ] ดู code ตัวอย่างจาก wk13.html slides เป็นแนวทาง
<!-- dashboard/templates/dashboard/index.html -->
<!DOCTYPE html>
<html lang="th">
<head>
<title>Text Generator Dashboard</title>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body x-data="{ training: false, epoch: 0, loss: 0, sample: '' }">
<!-- ★ ใส่รหัสนักศึกษาและชื่อ-นามสกุลตรงนี้ -->
<h1>รหัสนักศึกษา: 69000000</h1>
<h2>ชื่อ-นามสกุล: ชื่อ นามสกุล</h2>
<button @click="startTraining()">
เริ่มฝึกสอน
</button>
<p>Epoch: <span x-text="epoch"></span></p>
<p>Loss: <span x-text="loss"></span></p>
<h3>ตัวอย่างข้อความที่สร้าง:</h3>
<pre x-text="sample"></pre>
<canvas id="chart"></canvas>
<script>
function startTraining() {
training = true;
const es = new EventSource('/train/');
es.onmessage = function(e) {
const m = JSON.parse(e.data);
epoch = m.epoch;
loss = m.loss.toFixed(4);
if (m.sample) sample = m.sample;
drawChart(m.epoch, m.loss);
};
}
</script>
</body>
</html>
- รหัสนักศึกษา: เปลี่ยน 69000000 เป็นรหัสจริง
- ชื่อ-นามสกุล: เปลี่ยน ชื่อ นามสกุล เป็นชื่อจริง
- ปุ่ม "เริ่มฝึกสอน" เชื่อมกับ SSE endpoint
- แสดง ตัวอย่างข้อความ ที่ model สร้างขึ้นแบบ real-time
- ใช้ Canvas หรือ Chart.js สำหรับกราฟ loss
[สำคัญ] ห้ามลบ student ID และชื่อออกจากหน้า — ต้องเห็นชัดเจนเมื่อเปิดหน้า
# 1. Clone repo และ checkout branch git clone <DL69-repo> cd DL69 git checkout wk13 # 2. ติดตั้ง dependencies uv sync # 3. รัน server uv run manage.py runserver # 4. เปิดเบราว์เซอร์ # http://127.0.0.1:8000/ # → เห็นรหัสนักศึกษาและชื่อ # → กด "เริ่มฝึกสอน" # → เห็น loss ลดลง + ข้อความสร้างขึ้น real-time # → หลังฝึกเสร็จ เห็น samples.txt # 5. ตรวจสอบไฟล์ผลลัพธ์ ls dashboard/static/dashboard/ # → loss_curve.png # → samples.txt
- ขั้นตอนที่ 1: Clone repo แล้ว checkout branch wk13
- ขั้นตอนที่ 2: รัน uv sync เพื่อติดตั้ง dependencies
- ขั้นตอนที่ 3: รัน uv run manage.py runserver
- ขั้นตอนที่ 4: เปิด http://127.0.0.1:8000/
- ขั้นตอนที่ 5: ตรวจสอบว่าหน้า landing แสดงรหัสและชื่อ
[สำคัญ] ต้องรันได้ด้วย uv sync + uv run manage.py runserver เท่านั้น
- Branch name: wk13
- Repo: DL69 (GitHub repository ของนักศึกษา)
- สร้าง branch ใหม่จาก main
- Commit โค้ดทั้งหมดลง branch wk13
- Push ขึ้น GitHub
- แจ้ง URL ของ repo ให้อาจารย์
[สำคัญ] ห้าม commit ไฟล์ data ขนาดใหญ่ (>10MB) — ใช้ .gitignore
# สร้างและ push branch
git checkout -b wk13
git add .
git commit -m "wk13: Text Generator Dashboard"
git push origin wk13
# โครงสร้างไฟล์ที่ต้องมี
DL69/wk13/
├── pyproject.toml
├── manage.py
├── mysite/
├── dashboard/
│ ├── views.py
│ ├── ml/train.py ← โค้ดที่เขียน
│ └── templates/
│ └── dashboard/
│ └── index.html ← ใส่รหัส+ชื่อ
└── data/
└── corpus.txt ← ข้อความ
# ตรวจสอบก่อนส่ง
uv sync
uv run manage.py runserver
# → หน้า landing แสดงรหัสและชื่อ
# → กดเริ่มฝึกสอน → SSE ทำงาน
# → ได้ samples.txt + loss_curve.png
- โมเดลถูกต้อง (30%): LSTM language model ทำงานได้
- SSE Streaming (20%): ฝึกสอน + สร้างข้อความแบบ real-time ได้
- หน้า landing (15%): แสดงรหัสและชื่อชัดเจน
- ผลลัพธ์ (15%): samples.txt มีข้อความที่มีความหมาย, loss curve
- โค้ดสะอาด (10%): โครงสร้างดี, มี docstring
- รันได้จริง (10%): uv sync + runserver ไม่ error
[คะแนนรวม] 100% = คะแนนการบ้านสัปดาห์ที่ 13
# ตรวจสอบก่อนส่ง: # 1. uv sync สำเร็จ? uv sync # 2. server รันได้? uv run manage.py runserver # 3. หน้า landing แสดงรหัส+ชื่อ? # เปิด http://127.0.0.1:8000/ # 4. SSE ทำงาน? # กด "เริ่มฝึกสอน" แล้วเห็น # epoch, loss อัปเดต + sample text # 5. ผลลัพธ์ครบถ้วน? # - loss_curve.png มีอยู่ # - samples.txt มีข้อความ # 6. Branch ชื่อ wk13? git branch # → * wk13