본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 27. 21:21

「초소형 LLM」을 직접 만들어, 브라우저에서 마음대로 떠드는 도트 그래픽 금붕어를 키워보았다

요약

초소형 Transformer 모델을 직접 구현하여 브라우저에서 동작하는 도트 그래픽 금붕어 시뮬레이터를 제작했습니다. PyTorch로 설계한 디코더 전용 모델이 시간대에 따라 금붕어의 사고를 추론하여 말풍선으로 출력합니다.

핵심 포인트

  • PyTorch를 이용한 Decoder-only Transformer 모델 스크래치 구현
  • 60개의 제한된 어휘와 시간대별 컨텍스트를 활용한 초소형 모델 학습
  • FastAPI 백엔드와 Vanilla JS 프론트엔드를 활용한 심플한 시스템 구성
  • CSS steps()와 blend-mode를 활용한 1fps 레트로 도트 그래픽 구현

🚀 시작하며

브라우저 상에서 동작하는 원형 도트 그래픽 금붕어 디스플레이를 만들었습니다.

30분에 한 번씩, 백그라운드에서 동작하는 초소형 Transformer 모델이 그 당시의 시간대(아침·낮·밤·심야)에 따른 「금붕어의 사고」를 추론하여, 머리 위의 말풍선에 텍스트를 표시합니다.

또한, 화면상의 애니메이션은 모두 1fps(1초에 1프레임 갱신)의 프레임 단위 동작으로 설정하여, 레트로한 도트 그래픽 게임 같은 동작을 목표로 했습니다.

※ LLM(Large Language Model, 대규모 언어 모델)이라고 부르기에는 「L(Large)」이 아닌 초소형 토이 모델이지만, 내부의 아키텍처(구조)는 GPT 등과 같은 메커니즘으로 동작합니다.

코드는 모두 GitHub에 공개되어 있습니다.

GitHub 리포지토리: NAKAHARA-Yuki/goldfish_transformer

💡 개발 계기

계기는 Gigazine에서 소개되었던 「GuppyLM」에 관한 기사를 읽은 것이었습니다.

GIGAZINE 기사: 단 5분 만에 제로에서 언어 모델을 직접 만들 수 있는 「GuppyLM」 -
GitHub 리포지토리: arman-bd/guppylm

이 기사를 읽고, 「수억~수천억 파라미터의 대규모 모델 API를 호출하는 것뿐만 아니라, 내 손으로 Transformer 모델을 구축하여 브라우저 상에서 자율적으로 동작시키면 재미있겠구나」라는 생각이 들었습니다. 그래서 Python (PyTorch)와 FastAPI, 프론트엔드는 Vanilla HTML/CSS/JS를 사용하여 심플한 「금붕어의 뇌내 시뮬레이터」를 만들어 보기로 했습니다.

🛠️ 시스템 구성과 기술 선정

구성은 심플합니다.

AI 모델: PyTorch를 이용한 스크래치 구현의 Decoder-only Transformer 모델. -
백엔드: FastAPI / Uvicorn. HTML 서빙과 추론 API /api/generate를 제공. -
프론트엔드: HTML, CSS, JavaScript (라이브러리 미사용).

1fps의 레트로감을 내기 위한 CSS 블렌드

부드럽게 움직이는 매끄러운 애니메이션을 의도적으로 배제하고, 수초의 흔들림이나 거품의 움직임, 금붕어의 고개 돌림 등의 CSS 이징(Easing)을 모두 steps()로 통일했습니다.

또한, 시간대에 따른 배경색 변화를 표현하기 위해, 도트 그래픽 수중 배경 이미지에 대해 CSS의 background-blend-mode: multiply (곱하기/승산)를 사용하여, 도트 그래픽의 질감을 유지하면서 아침·낮·밤의 컬러를 블렌딩하고 있습니다.

🧠 모델 설계와 학습

1. 모델 정의

모델은 PyTorch의 nn.TransformerEncoder를 디코더로 사용한 초소형 Transformer입니다. 위치 인코딩(pos_emb)도 심플하게 Embedding 층으로 구현했습니다.

class GoldfishTransformer(nn.Module):
    def __init__(self, vocab_size, embedding_dim, nhead, num_layers, max_len=20):
        super().__init__()
        ...

2. 어휘와 학습 데이터

어휘(VOCAB)는 금붕어의 행동이나 감정을 나타내는 60개 단어(수이수이, 파쿠파쿠, 인간, 손가락, 조개껍데기, 기쁘다, 조용하다 등)로 제한했습니다.

학습 데이터에는 「아침」, 「낮」, 「밤」의 컨텍스트로 시작하는 총 20개의 사고 패턴 문장(모두 길이 6토큰 고정)을 준비하여 150 에포크(Epoch) 학습시켰습니다.

추론 시에는 현재 시각에 맞춘 시작 토큰(예: 아침이라면 ["<BOS>", "<MORNING>"])을 입력의 맨 앞에 주고, 그 뒤에 이어지는 말을 1토큰씩 예측해 나갑니다.

3. Temperature (샘플링 온도)에 의한 중얼거림 내용 전환

텍스트 생성의 예측 확률을 샘플링할 때, 시간대에 따라 Temperature (온도 파라미터)

# 추론 시 로짓(Logit) 조정 부분 발췌
logits = logits / temperature
probs = torch.softmax(logits, dim=-1)
...
  • 아침 (T = 0.9)・낮 (T = 0.7): 적절하게 예측이 흔들리며 자연스러운 혼잣말을 생성.
  • 밤 (T = 0.4): 확률의 변동성을 억제하여, 학습 데이터대로 "졸려", "조용"하게 잠들도록 수렴.
  • 심야 2:00~5:00 (T = 1.8): 로짓 (logits)의 차이를 극단적으로 균일하게 만들어, 지리멸렬한 "꿈 모드 (카오스한 발화)"를 강제.

이를 통해 심야에 브라우저를 열면 금붕어가 잠꼬대를 하는 듯한, 조금 기괴하면서도 애교 있는 움직임이 되었습니다.

📝 UI 레이아웃 조정 및 대응 사항

구현 과정에서 특히 미세 조정을 진행한 부분은 원형 디스플레이의 제약과 CSS 조정이었습니다.

둥근 화면에 요소를 담기 위한 레이아웃 조정

직경 280px의 정원 UI (border-radius: 50%)로 전체를 클리핑(clipping)했기 때문에, 금붕어를 크게 (96px) 하여 중앙에 배치하는 동시에 말풍선을 금붕어 바로 위 (top: 55px)에 고정했습니다. 조금이라도 벗어나면 원형 경계에서 글자가 잘려 보이기 때문에, CSS의 절대 위치 (absolute) 지정으로 조정을 진행했습니다.

또한, 브라우저의 해상도나 윈도우 크기에 따라 화면 하단에 불필요한 스크롤바가 표시되는 문제가 있어, body 요소에 overflow: hidden;을 추가하여 불필요한 스크롤 발생을 방지했습니다. 이를 통해 화면 중앙에 정원 수조만이 떠오르는 심플한 UI가 되었습니다.

👑 요약

최근에는 대규모 LLM의 API를 이용해 앱을 만드는 경우가 많지만, 초소형 규모의 트랜스포머 (Transformer) 모델을 직접 구현하고 파라미터 (parameter) 조정부터 추론 (inference) 동작까지 직접 제어하는 개발은 AI의 메커니즘을 체감하는 데 있어 매우 흥미로웠습니다.

현재는 브라우저 상에서 동작하는 웹 앱이지만, 앞으로는 이를 Raspberry Pi와 원형 LCD 디스플레이를 조합하여 실제로 책상 위에 놓을 수 있는 물리적인 가젯 (gadget)으로 직접 제작해 볼 계획입니다.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0