[이화여대 강의] 2. Deep Learning Software Stack 1 (3)

2024. 9. 21. 17:18 · 머신러닝 이모저모
목차
  1. CUDA
  2. Building PyTorch Custom CUDA Kernel
  3. CUDA semantics
  4. NCCL
  5. OpenAI Triton

이전 글 1 : https://mari970.tistory.com/83

이전 글 2 : https://mari970.tistory.com/84

 

[이화여대 강의] 2. Deep Learning Software Stack 1 (2)

https://mari970.tistory.com/83이번 포스팅은 Software stack 1 (1) 글의 첫번째 그림에서 Acceleration libraries 를 배워보자. 이번 포스팅에서 배울 것은 아래와 같다.TensorRTinference 시에 모델 배포 등에 사용하는

mari970.tistory.com

 

CUDA

c 의 extension. low level 코드이다.

GPU 하드웨어 아키텍처와 깊게 연관되어 GPU 프로그래밍을 구현되어있다.

 

Building PyTorch Custom CUDA Kernel

cuda kernel 을 직접 사용자가 설계하여 Pytorch 에 연결할 수 있다.

 

a = torch.randn(3,5)
b = torch.randn(3,1)

b_sized_a = b.expand_as(a)
a += b_sized_a

 

torch 가 broadcasting sum 이 안된다고 가정해보면,

dimension 이 다른 행렬에 대해 복사해서 더할 수 있도록 처리해야 한다. (expand_as())

 

__global__ void broadcast_sum_kernel(float *a, float *b, int x, int y, int size)
{
	int i = (blockIdx.x + blockIdx.y * gridDim.x) * blockIdx.x + threadIdx.x;
    if (i >= size) return;
    int j = i % x; i = i/x;
    int k = i % y;
    a[IDX2D(j, k, y)] += b[k];
 }

 

그러면 위와 같이 custom cuda kernel 을 만들 수 있다. (참조 : src/mathutil_cuda_kernel.cu)

** gpu 는 여러 thread 가 병렬적으로 동작할 수 있도록 구현되어있다. 각 thread 마다 id 가 존재한다.

thread 마다 행렬의 row 를 쪼개서 각각 더할 수 있도록 구현된다.

 

위처럼 만든 함수를 커널을 호출하는 wrapper 함수를 짜주고, nvcc 를 통해(.cu 파일을 컴파일해서) build 한다.

 

→ 더 알아보고싶다면 토치에 custom cuda extension 사용하는 방법을 찾을 수 있다.

 

CUDA semantics

  • tensorfloat-32 (TF32) : Ampere 디바이스(이상?) 에서 사용할 수 있는 precision
    • FP32 는 IEEE754 의 호환 가능한 precision 기준이다.
    • 위의 기준을 따르지 않고 nvidia 에서 개발한 precision 으로, exponent 와 mentissa bit 가 다르다.
    • 이를 사용할 때 머신러닝에서 accuracy 가 좀 더 좋다고 한다.
  • Reduced Precision Reduction in FP16 GEMMs
  • Reduced PRecision Reduction in BF16 GEMMs
  • CUDA streams

 

TensorFloat 32 (TF32)

matmul 이나 conv 등의 연산을 더 빨리 할 수 있도록 디자인됨.

 

# TF32 로 matmul 을 할 수 있도록
torch.backends.cuda.matmul.allow_tf32 = True

# TF32 를 cuDNN 에서 사용할 수 있도록
torch.backends.cudnn.allow_tf32 = True

 

10240x10240 을 행렬곱을 할 때 7배 빠른것을 확인할 수 있다.

 

Reduced precision reduction in FP16 GEMMs

 

Reduced precision reduction 이란? : 매트릭스 행렬곱에서 A 의 행과 B 의 열 (여러 값) 을 하나로 줄이는 연산이기 때문에 reduction 연산이라고 한다.

 

즉 precision 을 reduce (낮춘) 행렬곱 연산 이라는 뜻이다.

 

A (mxk) 와 B (kxn) 행렬을 계산 때 : k dimension 이 커질수록 reduced precision 을 켯을 때 속도 개선이 빨라진다.

→ 우리가 matmul 할 때 기본적으로 켜져있고, full precision 을 하려면 아래처럼 False 할 수 있다.

 

torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = False

 

2024-1 인공지능융합기반시스템개론 ❘ 이화여자대학교 심재형 교수님 ppt

 

CUDA streams

cuda stream 이란 GPU 에서 코드에 기술된 순서대로 동작하는 연산 sequence 를 의미한다.

 

cuda 를 사용하면 default stream 을 하나 사용하게 되고, 새로운 stream 이 생기면 이 디폴트 스트림과 병렬적으로 연산이 진행된다.

 

cuda = torch.device('cuda')

s = torch.cuda.Stream() # 새로운 stream 생성
A = torch.empty((100,100), device=cuda).normal_(0.0, 1.0)

with torch.cuda.stream(s):
	B = torch.sum(A)

 

위 코드에서는 새로운 s stream 을 생성하고 이 stream 에서 A 행렬을 더하는 동작이 일어나도록 한다.

하지만 위에서는 default stream 에서 A 행렬을 normalization 하고 있어서 다 끝나기 전에 새로운 stream 에서 작업하게되어 에러가 난다.

 

그래서 밑의 코드처럼

 

cuda = torch.device('cuda')

s = torch.cuda.Stream() # 새로운 stream 생성
A = torch.empty((100,100), device=cuda).normal_(0.0, 1.0)

s.wait_stream(torch.cuda.default_stream(cuda)) # 추가해준 코드

with torch.cuda.stream(s):
	B = torch.sum(A)
    
A.record_stream(s)

 

디폴트 스트림이 끝날 때 까지 기다렸다가 다른 스트림을 만들어서 sum 한다.

: 이를 synchronization 이라고 한다.

 

마지막에 해주는 record_stream 은 아래 문제를 해결하기 위해 사용한다.

처음에 디폴트 스트림에서 A 를 가지고있었고

새로운 스트림에서 B 가 A 를 이용하기 때문에 A 가 디폴트 스트림에서 de-allocation 될 수 있다.

 

record_stream 은 tensor 가 stream 에서 사용되고 있음을 표시한다.

그래서 tensor 가 deallocate 되었을 때 stream queue 에 있는 모든 work 가 끝날 때 까지 tensor memory 가 다른 텐서가 재사용하지 않도록 해준다. 

 


NCCL

NVIDIA Collective Communications Library 라고 한다. 

 

이 라이브러리에는 GPU 간 communication preimitives (기본 연산) 들을 제공한다. : AllReduce, Broadcast, AllGather, ReduceScatter 등..

NIVIDA gpu 에 최적화 되어있고, torch 에 bulit-in 되어있어 사용자가 직접 쓸 일은 없다고 한다.

 

torch.distributed.broadcast 와 같은 함수로 직접 내가 다른 지피유로 전송을 해줄 수 있기도 하다.

 


OpenAI Triton

openai triton 은 전문가가 아니어도 GPU 코드를 비교적 쉽게 쓸 수 있는 파이썬 언어이다.

즉, cuda 프로그래밍에서 파이썬을 사용할 수 있도록 하는 라이브러리로, 이는 c 파일로 래핑하고 바인딩하고 컴파일링할 필요가 없다는 뜻이다.

GPU 에서 병렬동작을 할 수 있도록 할 수 있다.

 

예를 들면 아래와 같은 새로운 activation 함수를 구현했을 때

 

def Act_new(x):
	x = torch.add(x,1)
	x = torch.sqrt(x)
	return x

 

torch.add 함수만으로도 많은 cuda 코드를 실행해야하므로 속도가 많이 느려질 수 있다.

 

하지만 사용자는 Act_new 함수가 2개의 커널로 쪼개지는 것이 아니라 하나의 kernel 안에서 add 와 sqrt 연산을 다 처리함으로서 데이터 이동에 대한 퍼포먼스 오버헤드가 사라지도록 짤 수 있다.

 

CUDA GPU 프로그래밍의 단점

쿠다 병렬 프로그래밍에는 3가지 관점으로 아키텍처를 알아야 한다.

 

DRAM (지피유 (밖의) 메모리) 로부터 데이터를 전송받을 때 memory coalesce 를 한다.

memory coalesce 란 global memory 에 여러개 thread 가 동시에 연속된 메모리 공간에 접근하도록 하는 것이다.

이는 데이터를 더 빨리 가져올수 있다.

프로그래머는 자신이 사용하는 알고리즘의 메모리 access 방식을 알고 coalesce 할 수 있도록 해줘야 한다.

 

사용자가 직접 read write 가 가능한 GPU 안의 Shared Memory 사용도 알아야하고

 

cuda 코드가 GPU 구조에 따라 어떻게 분산처리될 지도 알아야 한다.

 

⇒ Triton 은 위의 모든 과정을 자동화해줄 수 있다.

 

Example

Triton 을 사용하는 예시를 확인해보자.

 

** 아래 코드그림은 import 가 필요하다.

import triton module as tl

2024-1 인공지능융합기반시스템개론 ❘ 이화여자대학교 심재형 교수님 ppt

 

위 코드는 Triton 을 이용하여 element wise sum 연산을 병렬화한다.

 

pid 는 각 병렬로 수행되는 연산의 id 를 받는다.

 

메모리로부터 x y 각각(4x1) 을 (x_ptr=x의 포인터) 포인터를 이용해  tl.load 함수를 통해 가져온다.

그리고 각 element 마다 pid 가 0 1 2 3 이라고하면 이를 offset 으로 사용한다.

 

tl.store() : 을 이용하여 output 을 포인터의 해당 offset에 저장한다.

 

이 연산이 pid 4개 가 병렬로 동작하고 있는 것이다.

 

(cuda 도 비슷하지만) triton 은 data indexing 이 대부분의 코드에 해당한다.

 

Use Case

FlashAttention: Fast and Memory-Efficient Exact Attention with IO Awareness

 

일반적으로 구현된 어텐션 연산은 메모리 hierarchy 가 고려되지 않는다.

 

속도가 빠른 SRAM 을 최대한 활용하는 방식이 Flash attention 이다.

 

OpenAI Triton 은 torch 에서는 맨 오른쪽 그림처럼 matmul-dropout-softmax-mask-matmul 이 따로따로 구현되어있었다면 이를 하나의 kernel 로 구현할 수 있다. = Kernel Fusion 

'머신러닝 이모저모' 카테고리의 다른 글

DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models  (0) 2024.11.07
Peft save_pretrained() 에러 : UnboundLocalError: local variable 'active_adapters' referenced before assignment  (0) 2024.10.20
[이화여대 강의] 2. Deep Learning Software Stack 1 (2)  (0) 2024.09.20
[이화여대 강의] 2. Deep Learning Software Stack 1 (1)  (0) 2024.09.20
[이화여대 강의] Orientation  (0) 2024.09.20
  1. CUDA
  2. Building PyTorch Custom CUDA Kernel
  3. CUDA semantics
  4. NCCL
  5. OpenAI Triton
'머신러닝 이모저모' 카테고리의 다른 글
  • DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models
  • Peft save_pretrained() 에러 : UnboundLocalError: local variable 'active_adapters' referenced before assignment
  • [이화여대 강의] 2. Deep Learning Software Stack 1 (2)
  • [이화여대 강의] 2. Deep Learning Software Stack 1 (1)
섬섬옥수수
섬섬옥수수
컴공 AI 개발자가 되기 위한 노역입니다
섬섬옥수수
아날로그 인간의 컴공 되기
섬섬옥수수
전체
오늘
어제
  • 분류 전체보기
    • 백준 단계별 코딩 테스트
    • KB 논문 정리
    • Memory network 논문 정리
    • LLM 관련 논문 정리
    • Python 및 Torch 코딩 이모저모
    • Clustering 관련 논문 정리
    • 머신러닝 이모저모
    • 암호학

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • CUDA
  • constituency tree
  • e5-v
  • 심재형
  • PEFT
  • 인공지능융합기반시스템개론
  • ragas
  • 코딩테스트
  • GIT
  • dependency tree
  • 오블완
  • 하드웨어
  • eeve
  • 소프트웨어
  • 티스토리챌린지
  • 백준
  • 이화여대
  • vocabulary expansion
  • efficient and effective vocabulary expansion towards multilingual large language models
  • 문제풀이

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
섬섬옥수수
[이화여대 강의] 2. Deep Learning Software Stack 1 (3)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.