0. EulerStack의 자리 — LLM을 위한 아키텍처 기술 언어(ADL)
이 문서는 가장 먼저 읽는 튜토리얼 입니다. EulerStack 이 어떤 범주의 도구인지 먼저 이해하면, 뒤이은 튜토리얼의 모든 내용이 제자리에 놓입니다.
1. 한 문장 요약
EulerStack 은 LLM 을 위한 아키텍처 설계 언어 — Architecture Description Language (ADL) 입니다. 구조·훈련·서빙이 뒤섞인 Python 구현에서 "구조" 만 분리해, 그 목적을 위해 만들어진 선언형 언어 로 기술합니다. 반도체 설계가 Verilog/VHDL 로 겪은 것과 같은 종류의 추상화 도약입니다.
2. 왜 "설계 언어" 가 필요한가
DeepSeek-V3 의 MLA 어텐션을 한번 시험해 본다고 해봅시다. 오늘날의 작업 흐름은 이렇습니다.
- HuggingFace
transformers의modeling_llama.py를 포크한다. LlamaAttention을 수정한다 —W_q / W_k / W_v를W_q, W_kv_latent, W_k_up, W_v_up으로 재구성.forward와 KV 캐시 갱신 로직을 고친다 — 캐시의 shape 가 바뀌었으므로.save_pretrained / from_pretrained가 쓰는state_dict키 매핑을 추가한다.- 약 200~300 줄의 diff. 그 안에 담긴 의도 — "MLA 를 써본다" — 는 본질적으로 한 줄.
의도는 한 줄, 기계적 작업은 수백 줄. 이 간극이 세 가지 비용을 만듭니다.
- 리뷰 부담: PR 리뷰어가 "어디가 본질 변경이고 어디가 플러밍인가" 를 일일이 구분해야 합니다.
- 의도의 휘발: 두 달 뒤 같은 PR 을 되돌아보는 본인도 "무엇이 핵심이었나" 를 기억하기 어렵습니다.
- 암묵적 결합: 구조 변경이 훈련 루프, 토크나이저 어댑터, 서빙 시리얼라이저 와 얽혀서, 한 곳의 실수가 다른 파이프라인을 조용히 깨뜨립니다.
문제의 뿌리는 도구의 공백 입니다. 지금까지 LLM 모델은 늘 Python 같은 범용 프로그래밍 언어 로 기술됐습니다. Python 은 만능입니다 — 훈련 루프도, 데이터 전처리도, 서빙 어댑터도, 모델 구조도 전부 담습니다. 그 만능성 때문에 구조를 기술하는 데에는 전용이 아닙니다.
특화된 언어가 왜 차이를 만드는가? 전용 어휘는 세 가지를 제공합니다.
- 간결성 — 구조 변경이 의미상 한 줄이면, 표기도 한 줄입니다.
- 검증 가능성 — "MLA 의
latent_dim은d_model보다 작아야 한다" 같은 도메인 제약을 언어 차원에서 거부할 수 있습니다. 실행 전 catch. - 관심사 분리 — 구조는 구조, 훈련은 훈련, 서빙은 서빙. 각 축이 독립적으로 진화합니다.
EulerStack 은 이 셋을 목표로, LLM 아키텍처 기술만을 위한 선언형 언어 를 제공합니다.
3. HDL — 반도체 분야의 선례
"범용 코드 → 도메인 특화 선언형 언어" 라는 이동은 소프트웨어 공학 역사에서 여러 번 반복된 패턴입니다. EulerStack 이 따라가는 가장 가까운 선례는 반도체 설계 분야의 HDL (Hardware Description Language) 입니다.
3.1 Pre-HDL 시대 (~1984)
칩 설계자는 다음을 직접 다뤘다: - 회로도 (schematics) — 논리 게이트를 사람이 그림으로 그림 - 시뮬레이션 C 코드 — 동작을 imperative 하게 기술 - 수작업 최적화 — 레이아웃·타이밍을 엔지니어가 손으로
이 모든 것이 코드였다. 하지만 "칩을 기술하는" 전용 언어가 없었다. 한 파일에 "어떻게 동작하는가 (behavior)" 와 "어떻게 구현하는가 (implementation)" 가 뒤섞였다.
3.2 HDL 등장 (Verilog 1984, VHDL 1987)
Verilog / VHDL 이라는 아키텍처 기술 언어 (ADL) 가 등장했다. 특징:
- 선언형: "이 모듈의 입출력은 X, 동작은 Y" 를 진술
- 계층적: 서브모듈을 조립해 상위 모듈을 만듦
- 합성 vs. 시뮬레이션 분리: 같은 HDL 스펙이 시뮬레이션(검증)과 합성(실제 칩 생성)에 모두 소비됨
이것이 본질적 도약이었다. 칩 설계 노하우가 이제 Python 스타일 범용 코드가 아니라 전용 설계 언어로 표현 되기 시작했다.
3.3 LLM 과의 평행성
| Pre-HDL 칩 설계 | Pre-EulerStack LLM 설계 | |
|---|---|---|
| 매체 | 회로도 + 시뮬레이션 C | modeling_xxx.py (PyTorch) |
| 문제 | 동작·구현·검증이 한 파일에 섞임 | 구조·훈련·옵티마이저가 한 파일에 섞임 |
| 재사용 | copy-paste 기반 | copy-paste 기반 |
| 변경 추적 | 회로도 diff 불가 | 200 줄 diff 에 의도 묻힘 |
| Post-HDL 칩 설계 | Post-EulerStack LLM 설계 | |
|---|---|---|
| 매체 | Verilog/VHDL (ADL) | EulerStack YAML (ADL) |
| 관심사 분리 | 동작/합성/검증 분리 | 구조/훈련/서빙 분리 |
| 재사용 | 모듈·IP 코어 | 템플릿·프리셋 |
| 변경 추적 | HDL diff = 설계 변경 | YAML diff = 아키텍처 변경 |
핵심은 추상화 수준의 이동 입니다. "코드를 더 잘 쓰자" 가 아니라 "코드가 담당하던 층 위에 전용 설계 언어를 둔다" 는 것. 이것이 HDL 이 반도체 산업에 가져온 변화이고, EulerStack 이 LLM 설계자에게 가져오려는 것입니다.
4. EulerStack 이 구체적으로 무엇을 하는가
┌──────────────────────────────────────────────────────┐
│ EulerStack YAML (ADL) │ ← 설계 언어
│ schema_version: 1 │
│ model: { d_model: 4096, n_heads: 32, ... } │
│ layer_templates: { ... } │
│ layer_schedule: [ ... ] │
└────────────────┬────────────────────────────────────┘
│ compile (= HDL 의 "합성")
▼
┌──────────────────────────────────────────────────────┐
│ HuggingFace PreTrainedModel │ ← 실행 포맷
│ config.json + model.safetensors │
└────────────────┬────────────────────────────────────┘
│
├──► 훈련 (HF Trainer / Megatron / Axolotl)
├──► 튜닝 (LLaMA-Factory / torchtune / PEFT)
├──► 서빙 (vLLM / SGLang / TensorRT-LLM)
└──► 평가 (lm-eval-harness)
HDL 이 합성 과 시뮬레이션 을 분리한 것처럼, EulerStack 은 아키텍처 기술 과 훈련/서빙 실행 을 분리한다. 같은 YAML 스펙이 훈련에 들어가든, 서빙에 들어가든, 평가에 들어가든 구조 정의는 단일 진실의 원천 (single source of truth) 이다.
5. "전용 설계 언어" 가 주는 실질적 이득
HDL 이 반도체 설계자에게 가져온 것과 동일한 네 가지 이득을 EulerStack 이 LLM 설계자에게 제공한다.
5.1 관심사 분리 (Separation of Concerns)
HDL 이전의 엔지니어는 "이 게이트의 동작" 과 "이 게이트의 물리적 배치" 를 같은
문서에 썼다. HDL 은 이 둘을 분리했다. EulerStack 이전의 엔지니어는 modeling_
xxx.py 한 파일에 모델 구조 + 훈련 특화 로직 + 서빙 어댑터를 함께 썼다.
EulerStack 은 구조를 YAML 로, 훈련은 별도 스크립트로, 서빙은 HF 생태계에 맡기
는 삼각 분리를 강제한다.
5.2 리뷰가능성 (Review-ability)
HDL 을 쓰면 "이번 변경은 곱셈기 추가" 라는 의도가 diff 에 그대로 나온다. 회로도
시절에는 그림 1000 개를 비교해야 했다. EulerStack 에서도 동일. "이번 PR 은
attention 을 MLA 로 교체 + rope_theta 500K 로 확장" 이 YAML 5 줄 diff 로
표현된다. modeling_custom.py 200 줄 diff 에서 "무엇이 본질 변경인지" 를
발굴할 필요가 없다.
5.3 재현성 (Reproducibility)
HDL 스펙은 다른 엔지니어가 동일한 합성 도구로 합성했을 때 같은 칩을 얻는다.
EulerStack YAML 은 다른 사용자 / 다른 OS 에서 compile 했을 때 같은 HF
모델을 얻는다. compile 이 순수 함수 — YAML 입력만으로 결정적 출력.
5.4 조합성 (Composability)
HDL 의 모듈은 다른 모듈 안에 인스턴스로 들어가 복잡한 칩을 구성한다. EulerStack
의 layer_templates 는 layer_schedule 안에서 조합되고, 서로 다른 primitive
(MLA + MoE + Titans + ODE + execution_modes) 가 직교적으로 한 스펙에 얹힌다.
Tutorial 10 — Paper → YAML 의 arch_expert_kitchen_sink
가 이 조합성의 실제 사례.
6. 레고 블록의 인터페이스 — 다른 도구와의 관계
EulerStack 이 다른 도구와 맞물리는 지점은 명확하고 작다.
| 경계 | 흐르는 것 | 소유자 |
|---|---|---|
| 위 (입력) | 사람이 쓴 YAML 스펙 | 연구자 / 엔지니어 |
| 아래 (출력) | HF PreTrainedModel |
Transformers 생태계 |
| 우측 (메타) | config.v1_extensions |
플러그인이 해석 |
| 좌측 (역방향) | from_pretrained → YAML 역추론 (v1.2 예정) |
— |
들어오는 쪽: 한 줄 YAML diff = 한 번의 아키텍처 변경.
나가는 쪽: Llama / Mistral / Jamba 를 쓰던 파이프라인과 100% 동일한
AutoModelForCausalLM.from_pretrained(..., trust_remote_code=True) 계약.
"훈련 · 서빙 코드 그대로, 모델 정의만 교체" 가 가능.
7. 다른 "설계 언어" 도구와의 관계 — 경쟁이 아닌 계층
7.1 구조를 정의하는 다른 도구 (직접 비교)
| 도구 | 정의 방식 | EulerStack 과의 차이 |
|---|---|---|
| HF transformers | 사전 등록된 아키텍처 + trust_remote_code |
EulerStack 이 위 레이어 — YAML → HF 모델 |
| Modular Transformers (HF 실험) | modeling_xxx.py diff |
코드 레벨 에서 해결. EulerStack 은 설계 언어 레벨. HDL vs. 회로도 시뮬레이터 관계와 유사 |
| nanoGPT / litgpt | 단일 파일 reference impl | 교육용. EulerStack 은 그 위의 조립 레이어 |
| Ludwig | declarative ML framework | 개념 유사. LLM 구조 변형에는 얇음. EulerStack 이 훨씬 세밀 |
7.2 훈련 · 서빙 스택 — 보완 관계
HDL 이 칩 합성·시뮬레이션 도구와 공존 했듯, EulerStack 은 훈련·서빙 스택과 공존 한다.
| 도구 | 역할 | EulerStack 과 붙이는 법 |
|---|---|---|
| Megatron-LM / TorchTitan / GPT-NeoX | 분산 사전학습 | EulerStack 이 정의, 이쪽이 실행 |
| HF Trainer / Composer / Levanter | 단일~수노드 훈련 | AutoModelForCausalLM 로 연결 |
| Axolotl / LLaMA-Factory / torchtune | fine-tune | EulerStack 이 구조, 이쪽이 레시피 |
| PEFT / bitsandbytes / Unsloth | 효율 fine-tune / 양자화 | 직교. HF 호환이므로 자동 연동 |
| vLLM / SGLang / TensorRT-LLM | 서빙 | 직교. 표준 mixer 면 그대로 서빙 |
7.3 다른 문제를 푸는 도구
| 도구 | 하는 일 | 왜 EulerStack 과 다른가 |
|---|---|---|
| mergekit | 여러 pretrained weight 합치기 | Weight-level 연산. EulerStack 은 architecture-level |
| Once-for-All / AutoGluon / archai | NAS (자동 탐색) | 자동 탐색. EulerStack 은 수작업 조합의 깔끔한 비교 |
| Keras / PyTorch Lightning | 범용 DL runner | 범용. EulerStack 은 LLM 전용 ADL |
| fairseq | 연구용 seq2seq | 코드 기반. EulerStack 은 선언형 |
8. "언제 써야 하는가 / 언제 쓰면 안 되는가"
✅ EulerStack 을 꺼내야 할 순간
Q1. 논문에서 본 새 아키텍처 (DeepSeek-V3, Jamba, R1, Titans 등) 를 재현해
보고 싶다.
A. 프리셋 또는 YAML 5~20 줄이면 끝입니다. modeling_custom.py 작성 시간이
0 에 수렴. 튜토리얼 10: Paper → YAML 참조.
Q2. 논문에 없는 조합 (MLA + MoD + branched + MoE ...) 을 ablation 하고 싶다. A. EulerStack 이 유일하게 적합한 공개 도구. 같은 훈련 스크립트로 YAML diff 만 바꿔서 10~20 가지 조합을 검증 가능.
Q3. "아키텍처 변경 이력" 을 Git 으로 추적하고 싶다. A. YAML 파일이 곧 아키텍처. PR 하나에 "attention window 를 2048 → 4096, MoE 추가" 같은 의도가 그대로 보임.
Q4. 사내에서 사용자 정의 LLM 을 표준 HF 도구로 서빙하고 싶다.
A. compile → save_pretrained 후 vLLM / TGI 로 바로 서빙. v1 생태계의 4B / 7B
변형이 그대로 나감.
Q5. 신규 팀원에게 "왜 이 아키텍처를 이렇게 골랐는지" 를 가르치고 싶다. A. 53 개 프리셋의 3-tier 구성 (Validated → Hybrid → Experimental) 이 학습 경로 그 자체.
❌ EulerStack 이 맞지 않는 순간
Q1. "Llama 3 를 내 데이터로 fine-tune 하고 싶다." → LLaMA-Factory / Axolotl. EulerStack 은 pretrained weight 로딩이 1 급이 아님 (v1.2 로드맵).
Q2. "단일 노드에서 빠르게 훈련 레시피를 튜닝하고 싶다." → HF Trainer / Axolotl. EulerStack 은 구조 정의만 맡음. 훈련 루프는 포함하지 않는다 (HDL 이 fabrication 을 포함하지 않듯).
Q3. "1000 가지 아키텍처 변형을 자동으로 스윕해 최적을 찾고 싶다." → Once-for-All / archai 같은 NAS 도구. EulerStack 은 사람이 후보를 좁히고 소수를 깔끔하게 비교 하는 용도.
Q4. "Megatron 급 분산 사전학습을 곧바로 하고 싶다." → 정의는 EulerStack, 실행은 TorchTitan / Megatron 과 병행. EulerStack 은 분산 런처를 포함하지 않음.
Q5. "두 pretrained 모델을 merge 하고 싶다." → mergekit. EulerStack 은 weight-level 연산을 제공하지 않음.
9. "설계 언어" 가 실제로 무엇을 가능하게 하는가
같은 "5 줄 YAML diff" 가 이전 도구에서 무엇에 해당하는지 비교해 보자.
Case A. "Attention 을 MLA 로 바꾼다"
EulerStack YAML diff:
layer_templates:
decoder:
mixer:
type: attention
- attention: { qkv_bias: false }
+ attention: { qkv_bias: false, latent_dim: 384 }
1 줄 변경.
modeling_llama.py 기반 diff (추정):
- LlamaAttention.__init__ 전면 수정: W_q, W_k, W_v 를 W_q, W_kv_latent, W_k_up,
W_v_up, W_out 로 재구성
- forward 에서 QKV 계산 경로 변경
- KV cache 갱신 로직 수정 (shape 변경)
- save_pretrained / from_pretrained state_dict 키 매핑 추가
- 약 200~300 줄
Case B. "추론 단계와 답변 단계를 분리한다 (R1)"
EulerStack YAML 추가:
execution_modes:
- { name: think, max_tokens: 8192, kv_share: true, loss_weight: 0.0 }
- { name: answer, max_tokens: 2048, loss_weight: 1.0 }
transition:
type: special_token
token: "<think_end>"
6 줄 추가.
코드 기반 구현:
- Tokenizer 에 special token 등록
- GenerationMixin.generate() 재작성 (phase-aware)
- Loss weighting 을 훈련 루프에 추가
- config 직렬화 정의
- 약 500~700 줄 (훈련+생성+시리얼라이즈)
Case C. "Titans memory 를 모든 attention 레이어에 달고 inference 업데이트"
EulerStack YAML 추가:
memory:
type: neural_memory
update_at_inference: true
params: { hidden: 1024 }
inner_lr: 0.001
persistence: session
5 줄 추가.
코드 기반 구현:
- 새 nn.Module 클래스 작성 (forward + surprise)
- 각 layer 에 memory 결합
- step_memory_at_inference() 훅 노출
- gradient isolation 로직
- save/load state 키
- 약 300~500 줄 + 디버깅 스킬 요구
셋 모두 아키텍처 변경의 의도 는 YAML 몇 줄로 전부 담긴다. 그 의도의 구현 은 EulerStack 이 감당. 사용자는 설계 언어 수준에서 생각하면 됨.
10. 요약
EulerStack 은 LLM 아키텍처를 위한 전용 설계 언어 입니다. 지금까지 구조는
modeling_xxx.py 같은 범용 Python 코드 안에 흩어져 있었습니다. EulerStack 은
이를 한 층 끌어 올려, 오직 구조만을 기술하는 선언형 언어 로 옮깁니다. 이는
반도체 설계가 Verilog/VHDL 로 겪은 것과 같은 추상화 레벨 상승입니다.
훈련 · 서빙 · 튜닝은 각 분야의 전용 도구 (HF Trainer, vLLM, Axolotl 등) 가 훨씬 잘 수행합니다. 그래서 EulerStack 은 그 영역을 다루지 않습니다. 대신 설계 한 가지에 집중하고, 그 설계가 HF 생태계의 모든 실행 스택에 그대로 들어맞도록 설계됐습니다.
다음 단계
- 튜토리얼 1: 스펙 검증 — 실제 YAML 을 만들고 통과시키기.
- 튜토리얼 2: 프리셋 사용 — 53 개 출발점 중 본인 용도에 맞는 것 고르기.
- 튜토리얼 9: 신규 primitive — ADL 의 전체 어휘 (MLA / Jamba hybrid / R1 / Titans / MoD / Neural-ODE / 등).
- 튜토리얼 10: Paper → YAML — 논문 4 편을 대화로 YAML 에 옮기는 실전 케이스.