Puzzle 21: ์๋ฒ ๋ฉ Op
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด๊ณผ ์ฑ๋ฅ
๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋ ์ฐ์ฐ๊ณผ GPU ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ต์ ํ์ ์ด์ ์ ๋ง์ถฐ Part V๋ฅผ ์ด์ด๊ฐ๋๋ค.
Puzzle 20: 1D ํฉ์ฑ๊ณฑ Op์ ์ด์ด, ๋์ผํ ์ฐ์ฐ์ ์๋ก ๋ค๋ฅธ ์ปค๋ ๊ตฌํ์ด ์ฑ๋ฅ์ ์ผ๋ง๋ ๊ทน์ ์ธ ์ฐจ์ด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋์ง ์์๋ด ๋๋ค. ๋ฐฐ์ธ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- GPU ๋ฉ๋ชจ๋ฆฌ ๋ณํฉ์ด ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ
- ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋ ์ฐ์ฐ์์ ๊ทธ๋ฆฌ๋ ๊ตฌ์ฑ์ด ์ค์ํ ์ด์
- ์ต์ ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ผ๋ก ์ปค๋์ ์ค๊ณํ๋ ๋ฐฉ๋ฒ
- ์๋ก ๋ค๋ฅธ ์ค๋ ๋ฉ ์ ๋ต์ด ๊ฐ์ ธ์ค๋ ์ฑ๋ฅ ์ฐจ์ด
์ด ํผ์ฆ์ ์ด๋ค ์ฐ์ฐ์ ์ํํ๋๋๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ์ ์ด๋ป๊ฒ ์ ๊ทผํ๋๋๊ฐ ๋ ์ค์ํ ์ ์์์ ๋ณด์ฌ์ค๋๋ค.
๊ฐ์
์ด ํผ์ฆ์์๋ ์ ๊ฒฝ๋ง์ ํต์ฌ ๊ตฌ์ฑ ์์์ธ ์๋ฒ ๋ฉ(embedding) ์ฐ์ฐ์ ์ํ ๋ ๊ฐ์ง GPU ์ปค๋์ ๊ตฌํํฉ๋๋ค. ๋ ์ปค๋ ๋ชจ๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ์ง๋ง, ์๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ ์ฌ์ฉํ์ฌ ์๋นํ ์ฑ๋ฅ ์ฐจ์ด๋ฅผ ๋ณด์ ๋๋ค.
๋น๊ตํ ๋ ์ปค๋:
- 1D ๋ณํฉ(coalesced) ์ปค๋: ์ฐ์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ์ ์ต์ ํ
- 2D ๋น๋ณํฉ(non-coalesced) ์ปค๋: ๋น๊ต๋ฅผ ์ํ ์ต์ ํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด
์ด ๋น๊ต๋ฅผ ํตํด GPU ์ปค๋ ์ฑ๋ฅ์์ ๋ฉ๋ชจ๋ฆฌ ๋ณํฉ์ด ์ผ๋ง๋ ์ค์ํ์ง ์ฒด๊ฐํ ์ ์์ต๋๋ค.
๋ฐฐ๊ฒฝ: ์๋ฒ ๋ฉ ์ฐ์ฐ
์๋ฒ ๋ฉ ์ฐ์ฐ์ ์ด์ฐ์ ์ธ ํ ํฐ ์ธ๋ฑ์ค๋ฅผ ๋ฐ์ง ๋ฒกํฐ ํํ์ผ๋ก ๋ณํํฉ๋๋ค:
# Input: token indices
indices = [[1, 5, 2], [7, 1, 9]] # Shape: [batch_size, seq_len]
# Embedding table (learned parameters)
embedding_table = [ # Shape: [vocab_size, embed_dim]
[0.1, 0.2, 0.3, 0.4], # Token 0
[0.5, 0.6, 0.7, 0.8], # Token 1
[0.9, 1.0, 1.1, 1.2], # Token 2
# ... more tokens
]
# Output: embedded vectors
output[0,0] = embedding_table[1] # [0.5, 0.6, 0.7, 0.8]
output[0,1] = embedding_table[5] # lookup token 5's embedding
output[0,2] = embedding_table[2] # [0.9, 1.0, 1.1, 1.2]
# ... and so on
์ด ์ฐ์ฐ์ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋์ ๋๋ค. ์ฑ๋ฅ์ ์๋ฒ ๋ฉ ํ ์ด๋ธ์์ ์ผ๋ง๋ ํจ์จ์ ์ผ๋ก ์ฝ๊ณ ์ถ๋ ฅ ํ ์์ ์ธ ์ ์๋๋์ ๋ฌ๋ ค ์์ต๋๋ค.
ํ์ต ๊ฒฝ๋ก
์ด ํผ์ฆ์ ์ฒด๊ณ์ ์ธ ์ดํด๋ฅผ ์ํด ๋ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค:
๋ณํฉ vs ๋น๋ณํฉ ์ปค๋
์ฌ๊ธฐ์๋ถํฐ ์์ํ์ฌ ์ค์ ํผ์ฆ ์ฝ๋๋ฅผ ๊ตฌํํ๊ณ ์ปค๋ ๊ตฌํ์ ์ดํดํฉ๋๋ค.
๋ฌด์์ ํ๊ฒ ๋ ๊น์:
- ๋ ๊ฐ์ง GPU ์๋ฒ ๋ฉ ์ปค๋ ์์ฑ (1D ๋ณํฉ vs 2D ๋น๋ณํฉ)
- GPU ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด ํ์ต
- ๋์ผํ ์๊ณ ๋ฆฌ์ฆ์ ์๋ก ๋ค๋ฅธ ์ค๋ ๋ฉ ์ ๋ต์ผ๋ก ๊ตฌํํ๋ ์ฌ๋ก ํ์ธ
- Mojo์์์ ์ปค์คํ ์ฐ์ฐ ๋ฑ๋ก ์ดํด
์ฑ๋ฅ ๋น๊ต
์ปค๋ ์ฑ๋ฅ์ด ์ ๋ค๋ฅธ์ง, ๋ฉ๋ชจ๋ฆฌ ๋ณํฉ์ ์ด๋ก ์ ๊น์ด ํ๊ณ ๋ญ๋๋ค.
๋ฌด์์ ๋ฐฐ์ธ๊น์:
- GPU ์ฑ๋ฅ์์ ๋ฉ๋ชจ๋ฆฌ ๋ณํฉ์ด ์ค์ํ ์ด์
- ์ค๋ ๋ ๊ตฌ์ฑ์ด ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ ํ์ฉ์ ๋ฏธ์น๋ ์ํฅ
- ์ ๊ฒฝ๋ง ์ต์ ํ์ ๋ํ ์ค์ ์์ฌ์
- ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋ ์ฐ์ฐ์ ์ํ ์ต์ ํ ์ ๋ต
์์ํ๊ธฐ
GPU ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ๋ฅผ ํ๊ตฌํ ์ค๋น๊ฐ ๋์ จ๋์? ๋ณํฉ vs ๋น๋ณํฉ ์ปค๋ ์์ ์ฝ๋๋ฅผ ๊ตฌํํ ํ, ์ฑ๋ฅ ๋น๊ต ๋ก ๋์ด๊ฐ ์ฑ๋ฅ ์ฐจ์ด์ ์์ธ์ ์ดํดํด ๋ณด์ธ์.
๐ก ์ฑ๊ณต ํ: ์๋ก ๋ค๋ฅธ ๊ทธ๋ฆฌ๋ ๊ตฌ์ฑ(1D vs 2D)์ด ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง ์ฃผ์ ๊น๊ฒ ์ดํด๋ณด์ธ์. ์ด ํต์ฐฐ์ ์๋ฒ ๋ฉ์ ๋์ด ๋ค์ํ GPU ํ๋ก๊ทธ๋๋ฐ ์๋๋ฆฌ์ค์ ์ ์ฉ๋ฉ๋๋ค.