언어모델에서 모델의 의미 – 다른 사람이 훈련시킨 내가 쓸수 있는 체크포인트(Checkpoint)

언어모델에서 “모델”은 다른 사람이 훈련한 언어 모델의 체크포인트(checkpoint)를 의미합니다. 이 체크포인트는 모델이 훈련된 후 얻어진 가중치(weight)와 파라미터(parameter)의 상태를 저장하는 파일입니다. 체크포인트는 모델의 훈련 과정에서 정기적으로 저장되며, 훈련이 완료된 후에는 최종 모델의 상태를 나타냅니다.

다른 사람이 훈련한 언어 모델의 체크포인트를 사용하면, 해당 모델의 언어 생성 능력을 활용할 수 있습니다. 이 체크포인트를 소스코드에 로드하여 모델을 초기화하면, 해당 모델은 이미 훈련된 언어 모델의 능력을 갖게 됩니다. 따라서, 모델의 공개는 다른 사람이 훈련한 언어 모델의 상태를 저장한 체크포인트를 제공하여, 해당 모델을 활용할 수 있도록 하는 것을 의미합니다.

체크포인트(Checkpoint)는 언어 모델에서 모델의 상태를 나타내는 중요한 요소입니다. 언어 모델은 학습을 통해 언어 패턴을 파악하고, 문장 생성, 텍스트 분류 등의 작업을 수행하는데 사용됩니다. 모델은 많은 수의 파라미터로 구성되어 있으며, 이러한 파라미터는 모델의 학습 과정에서 업데이트됩니다.

체크포인트는 모델의 파라미터들을 저장하는 파일입니다. 학습이 진행되는 동안 주기적으로 체크포인트가 저장되며, 이는 모델의 특정 시점의 상태를 보존합니다. 체크포인트를 저장함으로써 모델의 학습 중간 결과물을 보존하고, 이후에 모델을 재사용하거나 이어서 학습할 수 있습니다. 또한, 체크포인트를 공유함으로써 다른 사용자들이 학습된 모델을 공유하고 사용할 수 있습니다.

따라서 언어 모델에서 체크포인트를 모델이라고 하는 이유는, 해당 파일이 모델의 파라미터를 저장하고 있는 중요한 구성 요소이며, 모델의 학습 상태와 정보를 보존하고 재사용하기 위해 사용되기 때문입니다.

체크포인트는 어디에서 구하는가

체크포인트는 일반적으로 학습된 모델의 결과물로서, 학습이 완료된 후 생성됩니다. 언어 모델의 체크포인트를 구하는 방법은 다음과 같습니다:

1. 직접 학습: 언어 모델을 직접 학습시키는 경우, 학습 과정에서 체크포인트를 생성할 수 있습니다. 학습이 완료된 후에는 체크포인트를 저장하고 추후에 모델을 재사용할 수 있습니다.

2. 사전 학습된 모델: 사전에 학습된 언어 모델의 경우, 해당 모델의 체크포인트는 원본 모델의 제공처나 오픈 소스 프로젝트에서 다운로드할 수 있습니다. 대표적으로 Hugging Face의 Transformers 라이브러리에서는 다양한 사전 학습된 언어 모델의 체크포인트를 제공합니다.

 

체크포인트를 구하는 방법은 모델의 학습 방식과 목적에 따라 달라질 수 있습니다. 직접 학습하는 경우에는 학습 프레임워크의 저장 기능을 사용하거나 사용자가 정의한 저장 방식을 활용할 수 있습니다. 사전 학습된 모델의 경우에는 제공되는 체크포인트 파일을 다운로드하여 사용할 수 있습니다.

언어모델의 소스코드가 공개된 것과 모델이 공개된 것의 차이는?

언어 모델의 소스코드가 공개된다는 것은 해당 언어 모델을 구현하는 코드가 공개되어 있다는 의미입니다. 이는 모델의 구조, 레이어, 학습 알고리즘 등을 이해하고 필요에 따라 수정하거나 확장할 수 있는 기회를 제공합니다.

반면에 모델이 공개된다는 것은 훈련된 언어 모델의 체크포인트 데이터나 미리 학습된 가중치가 공개되어 있다는 의미입니다. 이는 훈련된 모델을 로드하여 실제 자연어 처리 작업에 사용할 수 있도록 합니다. 공개된 모델은 이미 훈련된 상태이므로 추가적인 훈련이 필요하지 않고, 자연어 생성이나 문장 분류 등의 작업에 바로 활용할 수 있습니다.

요약하자면, 소스코드의 공개는 모델을 이해하고 수정할 수 있는 기회를 제공하며, 모델의 공개는 훈련된 모델을 활용하여 실제 작업을 수행할 수 있도록 합니다.

  • 트랜스포머들 사용한 GPT로서 라마 , 알파카 , 비쿠나  언어 모델의 오픈소스 언어 모델 중 중요한 것은 샵투스쿨 강의 트랜스포머 모델로 GPT만들기에 업데이트 중입니다.

토큰의 상위 확률 임계값 – 모델이 다음 토큰을 선택할 때 고려하는 확률 분포의 범위를 제한

텍스트 생성 모델에서 상위 확률 임계값은 다양성을 조절하는 매개변수입니다. 텍스트를 생성할 때 모델은 다음에 올 수 있는 다양한 토큰에 대한 확률 분포를 예측합니다. 이때 상위 확률 임계값을 설정하면, 모델은 예측 분포에서 상위 확률을 가진 토큰만을 고려하여 선택합니다.

예를 들어, 상위 확률 임계값을 0.95로 설정한 경우, 모델은 다음 토큰을 선택할 때 예측 분포에서 상위 5%에 해당하는 확률을 가진 토큰들만 고려합니다. 이렇게 함으로써 모델은 상위 확률을 가진 토큰들 중에서 더 다양한 선택을 할 수 있게 되며, 생성된 텍스트의 다양성과 유연성을 높일 수 있습니다.

따라서 상위 확률 임계값이 낮을수록 (예: 0.1) 모델은 더 많은 토큰을 고려하여 다양한 문장을 생성하게 되고, 상위 확률 임계값이 높을수록 (예: 0.95) 모델은 예측 분포에서 상위 확률을 가진 토큰만을 선택하여 더 일관된 문장을 생성하게 됩니다.

이때 상위확률 임계값은 보통 top_p로 쓰며 “Top Probability”의 약자입니다. 이는 GPT 모델에서 생성하는 텍스트에 대한 확률 분포에서 상위 확률을 가진 토큰들의 합을 의미합니다. top_p 값은 0에서 1 사이의 값을 가지며, 이 값은 모델이 다음 토큰을 선택할 때 고려하는 확률 분포의 상위 영역을 제한하는 역할을 합니다.

예를 들어, top_p 값을 0.95로 설정하면 모델은 다음 토큰 선택 시 누적 확률이 0.95를 넘지 않는 범위 내에서 가장 확률이 높은 토큰들을 선택합니다. 즉, top_p 값이 높을수록 모델이 다음 토큰을 선택할 때 더 많은 후보 토큰을 고려하게 되며, 이는 생성된 텍스트의 다양성을 높일 수 있습니다.

top_p 값이 낮을수록 모델은 더 확신 있는 예측을 하게 되므로, 생성된 텍스트의 일관성이 높아질 수 있습니다. 이는 모델이 상위 확률을 가진 토큰들 중에서 좀 더 명확한 선택을 하게 되는 효과를 가져옵니다.

모델 가중치 (checkpoint) – 학습된 모델의 파라미터 값들을 저장한 파일

모델 학습 과정에서 주기적으로 모델의 현재 상태를 저장하는 작업을 체크포인트라고 합니다. 이때 저장되는 것은 모델의 가중치(weight)입니다. 가중치는 모델의 학습 파라미터로서, 모델이 예측을 수행하는 데에 사용되는 중요한 값들입니다.

체크포인트는 학습 중간에 발생하는 예기치 않은 문제로 인해 모델의 상태가 손실되는 것을 방지하고, 학습을 중단한 후 다시 이어서 진행할 수 있도록 도와줍니다. 또한, 학습 과정에서 가장 좋은 성능을 보이는 모델의 가중치를 선택하여 추론(inference) 단계에서 사용할 수도 있습니다.

따라서 “checkpoint”라는 용어는 모델의 학습 중간에 저장되는 가중치의 상태를 나타내는 것으로, 모델의 재사용성과 학습의 지속성을 보장하기 위해 사용됩니다.

예를 들어, 딥러닝 모델을 사용하여 이미지 분류를 수행하는 프로젝트가 있다고 가정해봅시다. 모델을 학습시키는 동안 매 에폭(epoch)마다 모델의 가중치를 저장하는 체크포인트를 생성할 수 있습니다. 이러한 체크포인트 파일은 모델의 학습 과정에서의 중간 결과물이며, 나중에 모델을 다시 로드하여 학습을 재개하거나 이전 상태로 복원하는 데 사용할 수 있습니다. 따라서 “모델 가중치 (checkpoint)”는 학습된 모델의 상태를 저장한 파일을 의미합니다.

LORA (Low-Rank Adaptation) 저차원 표현 압축기법

LORA (Low-Rank Adaptation)는 딥러닝 모델의 효율적인 압축 기술 중 하나입니다. 이 기술은 딥러닝 모델의 파라미터를 저차원의 낮은 랭크 행렬로 근사하여 모델의 크기를 줄이고 계산 비용을 절감하는 방법입니다.

LORA는 대규모 딥러닝 모델을 보다 작은 크기로 압축함으로써 모델 배포 및 실행에 필요한 컴퓨팅 자원을 줄이는 장점을 가지고 있습니다. 이를 위해 LORA는 모델 파라미터 행렬을 낮은 랭크의 근사 행렬로 분해하고, 근사 행렬과 잔차 행렬 간의 차이를 최소화하는 방식으로 모델을 훈련시킵니다.

LORA는 높은 차원의 파라미터 공간을 낮은 차원으로 압축하여 모델의 메모리 사용량과 연산 비용을 줄이는 동시에 모델의 성능을 최대한 유지하는 것을 목표로 합니다. 이를 통해 모델을 보다 경량화하고, 모바일 기기나 에지 디바이스 등의 자원이 제한된 환경에서 효율적으로 모델을 배포하고 실행할 수 있게 됩니다.

LORA는 딥러닝 모델 압축 기술 중 하나로서, 고차원의 모델 파라미터를 저차원으로 효율적으로 표현하는 방법입니다. 이를 통해 모델 크기의 감소와 실행 속도의 향상을 이룰 수 있으며, 딥러닝 모델의 효율적인 활용을 가능하게 합니다.

언어 모델에서의 양자화: 파라미터 압축과 비트 수 감소

양자화는 단순히 말하면, 연속적인 값을 일정한 간격으로 나누어서 근사적인 값으로 표현하는 것입니다. 예를 들어, 연속적인 소수 값을 정수로 양자화한다고 가정해보겠습니다.

0부터 1까지의 범위를 0.1 간격으로 나누어보면 다음과 같습니다:
0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0

이렇게 나눈 값들을 양자화하여 정수로 표현한다면:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

이런식으로 연속적인 값들을 이산적인 값들로 근사화하여 표현하는 것이 양자화입니다. 이렇게 양자화를 하면, 값을 더 적은 비트 수로 표현할 수 있으며, 저장 공간을 절약하고 처리 속도를 향상시킬 수 있습니다. 그러나 양자화는 원래 값을 완벽하게 표현하지 않기 때문에, 약간의 정보 손실이 발생할 수 있습니다.

양자화는 컴퓨터 그래픽, 오디오 및 비디오 압축, 신경망 모델 압축 등 다양한 분야에서 활용되며, 효율적인 데이터 표현과 처리에 중요한 역할을 합니다.

언어모델에서의 양자화

언어 모델에서의 양자화는 모델의 파라미터를 더 작은 비트 수로 표현하는 기술입니다. 언어 모델은 많은 수의 가중치(weight)와 편향(bias)을 가지고 있는데, 이러한 가중치와 편향은 실수 값으로 표현됩니다. 그러나 이러한 실수 값들은 메모리를 많이 차지하고, 모델을 저장하고 전송하는 데에도 많은 비용이 발생할 수 있습니다.

양자화는 이러한 가중치와 편향을 더 작은 비트 수로 표현함으로써 메모리 요구량을 줄이고 모델의 크기를 줄일 수 있는 기술입니다. 예를 들어, 32비트 실수 값을 8비트 정수 값으로 양자화한다면, 해당 가중치의 표현 공간을 1/4로 줄일 수 있습니다. 이를 통해 모델의 메모리 사용량을 크게 줄일 수 있으며, 딥러닝 모델의 배포나 이식성 측면에서 이점을 얻을 수 있습니다.

양자화는 모델의 정확도에 약간의 영향을 줄 수 있지만, 적절하게 수행된다면 큰 성능 손실 없이 모델 크기를 줄일 수 있습니다. 따라서 양자화는 모바일 기기나 에지 디바이스에서의 실시간 추론, 대규모 모델의 분산 훈련 등의 시나리오에서 유용하게 활용될 수 있습니다.

AI의 성패는 온도조절에 있다 – 언어 모델에서의 ‘temperature(온도)’와 사람 사이의 관계 비유

언어 모델에서의 “temperature”를 성격에 비유하면, 차가운 사람은 보수적이고 일관된 행동을 취하는 경향이 있으며, 따뜻한 사람은 탐색적이고 다양한 행동을 취하는 경향이 있습니다.

차가운 사람은 일상적인 상황에서 예측 가능한 행동을 선호하고, 새로운 상황에서도 안정감을 주는 선택을 할 가능성이 높습니다. 마찬가지로, 온도가 낮은 언어 모델은 주로 예상 가능한 문장 구조와 흐름을 따르며, 일관된 결과를 생성하는 경향이 있습니다.

반면에, 따뜻한 사람은 새로운 경험을 탐색하고 예상치 못한 행동을 취하는 경향이 있습니다. 이와 유사하게, 온도가 높은 언어 모델은 다양한 문장 구조와 선택지를 탐색하며, 창의적이고 다양한 결과를 생성하는 경향이 있습니다.

따라서, 성격이 차가운 사람은 상대적으로 보수적이고 일관된 행동을 선호하며, 성격이 따뜻한 사람은 탐색적이고 다양한 행동을 선호합니다. 이와 마찬가지로, 온도가 낮은 언어 모델은 일관성과 예측 가능성을 제공하며, 온도가 높은 언어 모델은 창의성과 다양성을 촉진합니다.

temperature 와 출력 확률 분포

Temperature는 언어 모델에서 출력 확률 분포를 조정하는 역할을 합니다. 출력 확률 분포는 각 단어 또는 토큰에 대한 확률값을 나타내는데, 이 확률값은 모델이 해당 단어를 다음에 예측할 가능성을 나타냅니다.

Temperature 값은 일반적으로 0보다 크거나 같은 양수로 설정되며, 값이 낮을수록 출력 확률 분포가 “더욱 집중된” 형태를 가지게 됩니다. 즉, 낮은 Temperature 값은 모델의 예측을 보다 확신할 수 있는 높은 확률값을 갖게 합니다. 이는 모델이 보다 예상 가능하고 일관된 결과를 생성하는 경향을 갖게 합니다.

반면에, Temperature 값을 높일수록 출력 확률 분포가 “더욱 분산된” 형태를 가지게 됩니다. 높은 Temperature 값은 모델의 예측을 더욱 탐색적으로 만들어 다양한 가능성을 표현하게 합니다. 이는 모델이 보다 창의적이고 다양한 결과를 생성하는 경향을 갖게 합니다.

예를 들어, 낮은 Temperature 값을 사용하면 모델은 가장 높은 확률값을 가지는 단어를 선택하여 상대적으로 일관된 문장을 생성할 가능성이 높아집니다. 반면에, 높은 Temperature 값을 사용하면 모델은 다양한 단어에 대해 비교적 균등한 확률값을 가지며, 결과적으로 보다 다양하고 창의적인 문장을 생성할 수 있습니다.

따라서, Temperature는 언어 모델의 출력 확률 분포를 제어하여 예측의 일관성과 다양성을 조절하는데 사용되며, 적절한 Temperature 값을 선택함으로써 모델의 생성 결과를 원하는 대로 조정할 수 있습니다.

 

Temperature 와 언어모델의 정확도의 관계

Temperature와 언어 모델의 정확도 사이에는 상호 관계가 있습니다.

일반적으로, 낮은 Temperature 값을 사용하는 경우 모델의 정확도가 상대적으로 높아질 수 있습니다. 이는 낮은 Temperature 값이 모델의 출력 확률 분포를 더 집중시켜서 가장 높은 확률값을 갖는 단어를 선택하게 만들기 때문입니다. 따라서 모델은 더 일관된 예측을 할 가능성이 높아지며, 이는 정확도 측면에서 긍정적인 영향을 미칠 수 있습니다. 낮은 Temperature 값은 모델의 출력을 제한함으로써 더 신뢰할 수 있는 예측을 할 수 있도록 도와줍니다.

그러나 Temperature 값을 지나치게 낮게 설정하면 모델이 예측을 지나치게 확신하게 되어 다양성이 부족하고 과도하게 일관된 결과를 생성할 수 있습니다. 이는 모델의 예측이 지나치게 제한되는 단점이 될 수 있습니다. 따라서 정확도를 향상시키는 동시에 모델의 생성 다양성도 고려해야 합니다.

반면에, 높은 Temperature 값을 사용하는 경우 모델의 정확도가 상대적으로 낮아질 수 있습니다. 높은 Temperature 값은 모델의 출력 확률 분포를 더 분산시키고 다양한 가능성을 표현하게 합니다. 이는 모델이 더 다양한 결과를 생성하게 되어 정확도를 향상시키는 데에는 제한적일 수 있습니다. 높은 Temperature 값은 모델의 예측이 탐색적이고 창의적이게 만들어 다양한 결과를 생성할 수 있도록 도와줍니다. 그러나 다양성이 증가함에 따라 모델의 예측은 더 불확실해지고 정확도가 감소할 수 있습니다.

따라서, Temperature 값은 언어 모델의 정확도와 다양성 사이의 균형을 조절하는 역할을 합니다. 적절한 Temperature 값을 선택함으로써 원하는 정확도와 생성 다양성을 조절할 수 있으며, 이는 모델을 사용하는 특정 작업이나 목적에 따라 결정되어야 합니다.

언어 모델의 정확도와 다양성 사이의 균형을 조절하는 방법

언어 모델의 정확도와 다양성 사이의 균형을 조절하기 위해서는 Temperature 값을 조정하는 방법을 사용할 수 있습니다. Temperature 값을 적절하게 설정함으로써 모델의 출력을 조절하고 원하는 정확도와 다양성 수준을 달성할 수 있습니다.

다음은 언어 모델의 정확도와 다양성 사이의 균형을 조절하는 몇 가지 방법입니다:

1. Temperature 값 조정: Temperature 값을 높이면 모델의 출력 확률 분포가 분산되어 다양한 가능성을 표현할 수 있게 됩니다. 이는 모델의 다양성을 높이는데 도움이 됩니다. 반면에, Temperature 값을 낮추면 모델의 출력 확률 분포가 집중되어 더 정확한 예측을 할 수 있게 됩니다. 따라서, 정확도와 다양성 사이의 균형을 조절하기 위해 Temperature 값을 조정해보는 것이 좋습니다.

2. Top-k 샘플링: Top-k 샘플링은 모델이 다음 단어를 선택할 때 고려할 가능성 있는 단어의 수를 제한하는 방법입니다. 작은 k 값은 모델의 선택지를 제한하여 더 정확한 예측을 유도할 수 있습니다. 큰 k 값은 모델에게 더 많은 선택지를 제공하여 다양성을 높일 수 있습니다.

3. Top-p 샘플링 (또는 Nucleus 샘플링): Top-p 샘플링은 모델이 다음 단어를 선택할 때 고려할 가능성 있는 단어의 누적 확률을 제한하는 방법입니다. 작은 p 값은 모델의 선택지를 제한하여 더 정확한 예측을 유도할 수 있습니다. 큰 p 값은 모델에게 더 많은 선택지를 제공하여 다양성을 높일 수 있습니다. 이 방법은 GPT 모델에서 “nucleus sampling”으로도 알려져 있습니다.

4. 토크나이저의 특정 설정 조정: 언어 모델의 정확도와 다양성은 토크나이저의 특정 설정에 따라 다를 수 있습니다. 예를 들어, 토크나이저의 문장 분리 기준, 특수 문자 처리, 대소문자 변환 등의 설정을 변경하여 모델의 출력을 조절할 수 있습니다.

정확도와 다양성 사이의 균형은 사용하는 모델과 특정 작업의 요구사항에 따라 다를 수 있습니다. 따라서, 실험과 조정을 통해 원하는 결과를 얻을 수 있는 최적의 방법을 찾아야 합니다.

단 60줄의 코드로 GPT를 만들었다고?

60줄의 코드로 GPT를 만든 친구가 있네요.  깃헙 저장소에 코드가 있는데요, 너무 짧아 콜랩에서도 돌아가게 해 봤습니다.
여러분이 질문도 넣어보고 파라미터 값도 변경해 가면서 테스트해 보세요. 또 코드가 짧으니 GPT학습에도 좋습니다.

콜랩에 실행되는 코드의 설명입니다.

이 코드는 GPT-2 모델을 실행하는 함수와 그와 관련된 여러 유틸리티 함수들로 구성되어 있습니다. 주요 함수와 기능은 다음과 같습니다:

  1. gelu(x): GELU (Gaussian Error Linear Unit) 활성화 함수를 구현한 함수입니다.
  2. softmax(x): 소프트맥스 함수를 구현한 함수입니다. 입력 배열의 각 요소를 소프트맥스 함수에 적용하여 확률 분포로 변환합니다.
  3. layer_norm(x, g, b, eps): 레이어 정규화를 수행하는 함수입니다. 입력 배열을 정규화하고, 스케일과 오프셋을 적용합니다.
  4. linear(x, w, b): 선형 변환을 수행하는 함수입니다. 입력 배열과 가중치 행렬, 편향 벡터를 곱하여 출력을 계산합니다.
  5. ffn(x, c_fc, c_proj): 피드포워드 신경망(feed-forward network)을 구현한 함수입니다. 입력 배열을 선형 변환하고, GELU 활성화 함수를 적용한 후 다시 선형 변환합니다.
  6. attention(q, k, v, mask): 어텐션(attention) 메커니즘을 구현한 함수입니다. 주어진 쿼리(query), 키(key), 값(value) 배열을 사용하여 어텐션 가중치를 계산하고, 가중합을 구합니다.
  7. mha(x, c_attn, c_proj, n_head): 멀티 헤드 어텐션(multi-head attention)을 수행하는 함수입니다. 입력 배열을 선형 변환한 후, 각각의 어텐션 헤드로 분리합니다. 어텐션 가중치를 계산하고 헤드를 다시 병합한 후, 선형 변환을 적용합니다.
  8. transformer_block(x, mlp, attn, ln_1, ln_2, n_head): 트랜스포머 블록(transformer block)을 구현한 함수입니다. 멀티 헤드 어텐션과 피드포워드 신경망을 포함하며, 입력 배열에 이러한 계층을 적용하여 출력을 계산합니다.
  9. gpt2(inputs, wte, wpe, blocks, ln_f, n_head): GPT-2 모델을 실행하는 함수입니다. 토큰과 위치 임베딩을 결합한 후, 여러 개의 트랜스포머 블록을 순차적으로 통과시켜 출력을 계산합니다.
  10. `generate(inputs, params, n_head, n_tokens_to_generate)` 함수는 입력 시퀀스(inputs), 모델 파라미터(params), 헤드 개수(n_head), 생성할 토큰 개수(n_tokens_to_generate)를 인자로 받아서 텍스트를 생성하는 함수입니다.함수 내부에서는 다음과 같은 작업이 수행됩니다:

    1. `tqdm` 라이브러리를 사용하여 “generating” 메시지와 함께 진행 상황을 표시합니다.

    2. 지정된 토큰 개수(n_tokens_to_generate)만큼 반복하는 루프를 실행합니다. 이 루프는 자동 회귀적인 디코딩을 수행합니다.

    3. `gpt2(inputs, **params, n_head=n_head)`를 호출하여 모델의 순방향 전파(forward pass)를 수행하고 로짓(logits)을 얻습니다.

    4. 로짓 중 가장 큰 값을 가진 인덱스를 선택하여 다음 토큰을 결정합니다. 이는 탐욕적인(greedy) 샘플링 방식입니다.

    5. 예측된 다음 토큰을 입력 시퀀스(inputs)에 추가합니다.

    6. 생성된 텍스트를 반환하기 위해 입력 시퀀스(inputs)에서 마지막에 위치한 n_tokens_to_generate 개수만큼의 토큰을 잘라냅니다.

    따라서 `generate` 함수를 호출하면 입력 시퀀스(inputs)와 모델 파라미터(params)를 사용하여 지정된 개수의 토큰을 생성하고, 해당 토큰들을 반환합니다. 이러한 토큰들은 후속 처리를 통해 텍스트로 디코딩될 수 있습니다.

아래는 코드입니다.

 

 

#로칼 컴퓨터에서 할거 아니니까, picoGPT/gpt2.py 의 내용 그대로 실행되게 붙여 넣음
import numpy as np


def gelu(x):
    return 0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * x**3)))


def softmax(x):
    exp_x = np.exp(x - np.max(x, axis=-1, keepdims=True))
    return exp_x / np.sum(exp_x, axis=-1, keepdims=True)


def layer_norm(x, g, b, eps: float = 1e-5):
    mean = np.mean(x, axis=-1, keepdims=True)
    variance = np.var(x, axis=-1, keepdims=True)
    x = (x - mean) / np.sqrt(variance + eps)  # normalize x to have mean=0 and var=1 over last axis
    return g * x + b  # scale and offset with gamma/beta params


def linear(x, w, b):  # [m, in], [in, out], [out] -> [m, out]
    return x @ w + b


def ffn(x, c_fc, c_proj):  # [n_seq, n_embd] -> [n_seq, n_embd]
    # project up
    a = gelu(linear(x, **c_fc))  # [n_seq, n_embd] -> [n_seq, 4*n_embd]

    # project back down
    x = linear(a, **c_proj)  # [n_seq, 4*n_embd] -> [n_seq, n_embd]

    return x


def attention(q, k, v, mask):  # [n_q, d_k], [n_k, d_k], [n_k, d_v], [n_q, n_k] -> [n_q, d_v]
    return softmax(q @ k.T / np.sqrt(q.shape[-1]) + mask) @ v


def mha(x, c_attn, c_proj, n_head):  # [n_seq, n_embd] -> [n_seq, n_embd]
    # qkv projection
    x = linear(x, **c_attn)  # [n_seq, n_embd] -> [n_seq, 3*n_embd]

    # split into qkv
    qkv = np.split(x, 3, axis=-1)  # [n_seq, 3*n_embd] -> [3, n_seq, n_embd]

    # split into heads
    qkv_heads = list(map(lambda x: np.split(x, n_head, axis=-1), qkv))  # [3, n_seq, n_embd] -> [3, n_head, n_seq, n_embd/n_head]

    # causal mask to hide future inputs from being attended to
    causal_mask = (1 - np.tri(x.shape[0], dtype=x.dtype)) * -1e10  # [n_seq, n_seq]

    # perform attention over each head
    out_heads = [attention(q, k, v, causal_mask) for q, k, v in zip(*qkv_heads)]  # [3, n_head, n_seq, n_embd/n_head] -> [n_head, n_seq, n_embd/n_head]

    # merge heads
    x = np.hstack(out_heads)  # [n_head, n_seq, n_embd/n_head] -> [n_seq, n_embd]

    # out projection
    x = linear(x, **c_proj)  # [n_seq, n_embd] -> [n_seq, n_embd]

    return x


def transformer_block(x, mlp, attn, ln_1, ln_2, n_head):  # [n_seq, n_embd] -> [n_seq, n_embd]
    # multi-head causal self attention
    x = x + mha(layer_norm(x, **ln_1), **attn, n_head=n_head)  # [n_seq, n_embd] -> [n_seq, n_embd]

    # position-wise feed forward network
    x = x + ffn(layer_norm(x, **ln_2), **mlp)  # [n_seq, n_embd] -> [n_seq, n_embd]

    return x


def gpt2(inputs, wte, wpe, blocks, ln_f, n_head):  # [n_seq] -> [n_seq, n_vocab]
    # token + positional embeddings
    x = wte[inputs] + wpe[range(len(inputs))]  # [n_seq] -> [n_seq, n_embd]

    # forward pass through n_layer transformer blocks
    for block in blocks:
        x = transformer_block(x, **block, n_head=n_head)  # [n_seq, n_embd] -> [n_seq, n_embd]

    # projection to vocab
    x = layer_norm(x, **ln_f)  # [n_seq, n_embd] -> [n_seq, n_embd]
    return x @ wte.T  # [n_seq, n_embd] -> [n_seq, n_vocab]


def generate(inputs, params, n_head, n_tokens_to_generate):
    from tqdm import tqdm

    for _ in tqdm(range(n_tokens_to_generate), "generating"):  # auto-regressive decode loop
        logits = gpt2(inputs, **params, n_head=n_head)  # model forward pass
        next_id = np.argmax(logits[-1])  # greedy sampling
        inputs.append(int(next_id))  # append prediction to input

    return inputs[len(inputs) - n_tokens_to_generate :]  # only return generated ids


def main(prompt: str, n_tokens_to_generate: int = 40, model_size: str = "124M", models_dir: str = "models"):
    from utils import load_encoder_hparams_and_params

    # load encoder, hparams, and params from the released open-ai gpt-2 files
    encoder, hparams, params = load_encoder_hparams_and_params(model_size, models_dir)

    # encode the input string using the BPE tokenizer
    input_ids = encoder.encode(prompt)

    # make sure we are not surpassing the max sequence length of our model
    assert len(input_ids) + n_tokens_to_generate < hparams["n_ctx"]

    # generate output ids
    output_ids = generate(input_ids, params, hparams["n_head"], n_tokens_to_generate)

    # decode the ids back into a string
    output_text = encoder.decode(output_ids)

    return output_text

인공지능이용 보안기술 – 전자상거례에서 사기성 주문 여부 판단

머신러닝은 사기성 주문 판별에 유용한 도구 중 하나입니다. 일반적으로, 사기성 주문 판별을 위한 머신러닝 모델을 만들기 위해서는 다음과 같은 단계를 거칩니다.

  1. 데이터 수집: 머신러닝 모델을 학습시키기 위해서는 레이블링된 사기성 주문 데이터와 정상 주문 데이터가 필요합니다.
  2. 데이터 전처리: 수집된 데이터를 전처리하여 모델 학습에 적합한 형식으로 변환합니다. 이 단계에서는 데이터의 결측치, 이상치 등을 처리하고, 필요한 특성을 추출하거나 생성합니다.
  3. 모델 학습: 전처리된 데이터를 사용하여 머신러닝 모델을 학습시킵니다. 이 단계에서는 주로 분류 알고리즘을 사용하여 주문이 사기인지 아닌지를 판별하는 이진 분류 모델을 만듭니다.
  4. 모델 평가 및 성능 향상: 학습된 모델을 평가하고 성능을 향상시키기 위해 모델의 하이퍼파라미터를 조정하거나 다른 분류 알고리즘을 시도할 수 있습니다. 또한, 새로운 데이터에 대한 모델의 예측 성능을 평가하기 위해 검증 데이터를 사용할 수 있습니다.
  5. 모델 배포: 학습된 모델을 실제 운영 환경에 배포하여 사용합니다. 이 단계에서는 모델을 서버나 클라우드에 배포하거나, 모델 API를 만들어 다른 애플리케이션에서 사용할 수 있도록 합니다.

이러한 과정을 거쳐 만들어진 머신러닝 모델은 주문 데이터의 특징을 분석하여 사기성 주문 여부를 판단할 수 있습니다. 주문의 금액, 결제 방식, 주문자 정보, 배송지 정보 등 다양한 특성을 고려하여 모델이 예측한 결과를 바탕으로 사기성 주문을 차단하거나 확인하는 등의 대응 방안을 수립할 수 있습니다.

패턴 분석 기술을 사용하여 사기성 주문 여부를 판단하는 예시 코드는 다음과 같습니다.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 데이터셋을 로드합니다.
dataset = pd.read_csv('주문데이터.csv')

# 입력 데이터와 출력 데이터를 분리합니다.
X = dataset.drop('fraud', axis=1)
y = dataset['fraud']

# 학습 데이터와 테스트 데이터를 분리합니다.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 모델을 정의하고 학습합니다.
model = DecisionTreeClassifier()
model.fit(X_train, y_train)

# 테스트 데이터로 예측을 수행합니다.
y_pred = model.predict(X_test)

# 모델의 정확도를 측정합니다.
accuracy = accuracy_score(y_test, y_pred)
print('모델의 정확도: {:.2f}%'.format(accuracy * 100))

이 예시 코드에서는 사기성 주문 여부를 판단하는 모델을 학습하고, 테스트 데이터로 예측을 수행하여 모델의 정확도를 측정합니다. 이때, 입력 데이터로는 주문 내역의 금액, 결제 방법, IP 주소 등의 정보가 사용될 수 있습니다. 이러한 정보를 바탕으로 모델은 주문이 사기인지 아닌지를 판단하게 됩니다.

인공지능이용 보안기술 – 스팸 필터링

인공지능은 보안 분야에서도 다양하게 활용됩니다. 스팸 필터링은 이메일이나 메시지 등에서 스팸으로 분류되는 내용을 차단하는 기술입니다. 인공지능을 활용하면, 머신러닝 알고리즘을 이용해 스팸 메시지의 패턴을 학습하고, 새로운 스팸 메시지를 탐지하여 차단할 수 있습니다.

예들 들어 브라우저의 JavaScript 코드가 사용자의 행동 패턴과 이전 상호작용에 대한 정보를 수집하여, – 예를 들어 클릭, 키보드 입력, 마우스 이동 등- 이런 패턴을 기반으로 사용자가 로봇인지 아닌지를 판단합니다.
기술의 간단한 예시를 보겠습니다.

실행하기

 

# 데이터셋을 정의합니다.
dataset = [
  {'input': [0.1, 0.2, 0.3], 'output': [1]},
  {'input': [0.4, 0.5, 0.6], 'output': [1]},
  {'input': [0.7, 0.8, 0.9], 'output': [0]},
  {'input': [0.2, 0.3, 0.4], 'output': [1]},
  {'input': [0.5, 0.6, 0.7], 'output': [0]}
]

위 코드에서 입력 데이터의 패턴은 ‘input’ 키에 대응되는 값입니다. 이 예시에서는 각 데이터가 3차원 벡터로 이루어져 있으며, 이 벡터는 사용자의 클릭, 키보드 입력, 마우스 이동 등의 동작을 수치화한 값일 수 있습니다. 모델은 이러한 입력 데이터의 패턴을 학습하여, 로봇이 아닌 사용자와의 차이점을 찾아내고 이를 바탕으로 로봇 여부를 판단합니다. 따라서 입력 데이터의 패턴이 모델의 정확도와 판단력에 큰 영향을 미치게 됩니다. 이를 실제 웹사이트에서 사용하려면, 이벤트 리스너를 추가하여 사용자의 클릭, 키보드 입력, 마우스 이동 등의 동작을 감지하고 이를 모델에 입력 데이터로 전달하면 됩니다.

예를 들어 아래는 마우스 클릭 이벤트 리스너를 추가하는 예시입니다.

# 예시: 마우스 클릭 이벤트 리스너 추가
from browser import document

def on_mouse_click(event):
    # 클릭 위치를 수치화하여 input 값으로 사용
    x = event.clientX
    y = event.clientY
    input_data = [x, y]

    # 모델에 입력 데이터를 전달하여 결과를 예측
    result = model.predict(input_data)

    # 결과에 따른 동작 수행
    if result > 0.5:
        # 로봇일 가능성이 높음
        print("Suspicious activity detected!")
    else:
        # 로봇이 아닐 가능성이 높음
        print("Human user")
        
document.bind('click', on_mouse_click)

이외에도, 키보드 입력, 마우스 이동 등의 이벤트를 감지하는 방법은 다양하므로, 상황에 맞게 적절한 이벤트 리스너를 추가하여 사용자의 동작을 입력 데이터로 변환하여 모델에 전달할 수 있습니다.

전체 코드는 다음과 같습니다.

import tensorflow as tf
import numpy as np

# 데이터셋을 정의합니다.
dataset = [
  {'input': [0.1, 0.2, 0.3], 'output': [1]},
  {'input': [0.4, 0.5, 0.6], 'output': [1]},
  {'input': [0.7, 0.8, 0.9], 'output': [0]},
  {'input': [0.2, 0.3, 0.4], 'output': [1]},
  {'input': [0.5, 0.6, 0.7], 'output': [0]}
]

# 모델을 정의합니다.
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units=4, input_shape=[3], activation='relu'))
model.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam')

# 모델을 학습합니다.
xs = np.array([data['input'] for data in dataset])
ys = np.array([data['output'] for data in dataset])
history = model.fit(xs, ys, epochs=100)

# 예측합니다.
input = np.array([0.3, 0.4, 0.5])
output = model.predict(np.array([input]))
print(output[0][0])

 

 

[cafe AI] 머신러닝을 이용한 이미지 인식

  • 이 강의는 shop2world 의 캐나다 몬트리올에서 진행되는 일반인 대상의 AI 강의인 cafe AI 2023 강의 시리즈 교재입니다.
  • 강의 참여를 원하시는 분은 info@shop2world.com 으로 신청 주세요.
    강의 언어는 영어, 불어, 한국어 입니다.
  • 강의 결과 실행: [cafe AI] 머신러닝을 이용한 이미지 인식기법

머신러닝을 이용하여 이미지를 인식하는 예시로는, 손글씨 숫자 인식 프로그램이 있습니다. 이 프로그램은 숫자가 쓰인 이미지를 입력으로 받아 머신러닝 알고리즘을 통해 숫자를 인식합니다.

머신러닝 알고리즘은 먼저 숫자 이미지 데이터셋을 사용해 학습합니다. 학습을 통해 이미지에서 특징을 추출하고, 이를 바탕으로 숫자를 인식할 수 있는 모델을 만들어냅니다. 이렇게 만들어진 모델은 새로운 이미지를 입력으로 받아, 학습한 내용을 바탕으로 숫자를 인식할 수 있습니다.

이러한 손글씨 숫자 인식 프로그램은 손글씨 숫자를 자동으로 인식해주는데 사용될 수 있습니다. 이를 응용하여 우편물에서 우편번호를 인식하는 등 다양한 분야에서 활용될 수 있습니다.

먼저 실행을 해 보겠습니다.
실행하기

이 예제에서는 MNIST 데이터셋을 사용합니다. MNIST는 0부터 9까지의 숫자 이미지 데이터셋으로, 이미지 분류 문제에서 가장 대표적인 데이터셋 중 하나입니다.
Keras가 제공하는 데이터셋을 이용합니다.

먼저, 필요한 라이브러리와 데이터를 불러옵니다.

import tensorflow as tf
from tensorflow import keras
import numpy as np
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

이제 데이터셋을 살펴보겠습니다.

print(train_images.shape)   # (60000, 28, 28)
print(len(train_labels))    # 60000
print(test_images.shape)    # (10000, 28, 28)
print(len(test_labels))     # 10000

총 60,000개의 학습 데이터와 10,000개의 테스트 데이터가 있습니다. 각 이미지는 28×28 크기의 흑백 이미지입니다.

데이터 전처리를 수행합니다. 픽셀값을 0과 1 사이로 정규화하고, 레이블을 범주형으로 변환합니다.

train_images = train_images / 255.0
test_images = test_images / 255.0
train_labels = keras.utils.to_categorical(train_labels)
test_labels = keras.utils.to_categorical(test_labels)

이제 모델을 구성합니다. 2개의 은닉층과 1개의 출력층으로 구성된 인공신경망을 사용합니다.

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(64, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])

이제 모델을 컴파일합니다.

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

모델을 학습시킵니다.

model.fit(train_images, train_labels, epochs=5)

마지막으로 모델을 평가합니다.

test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)

전체 코드는 다음과 같습니다.

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist

# MNIST 데이터셋 로드
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 데이터 전처리
x_train = x_train / 255.0
x_test = x_test / 255.0

# 모델 구성
model = tf.keras.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])

# 모델 컴파일
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 모델 훈련
model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))

# 모델 평가
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print('\nTest accuracy:', test_acc)

# 예측 결과 확인
predictions = model.predict(x_test)

# 예측 결과 시각화
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plt.imshow(x_test[i], cmap='gray')
  plt.axis('off')
  predicted_label = np.argmax(predictions[i])
  true_label = y_test[i]
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plt.bar(range(10), predictions[i], color=color)
  plt.xticks(range(10))
  plt.ylim([0, 1])
  plt.tight_layout()

이 코드는 TensorFlow를 사용하여 MNIST 데이터셋에 있는 손글씨 숫자 이미지를 분류하는 모델을 학습하고, 학습된 모델을 이용하여 테스트 데이터셋에 있는 이미지를 분류하는 코드입니다. 코드 실행을 위해서는 TensorFlow와 NumPy, Matplotlib 라이브러리가 필요합니다. 또한, Google Colab에서 실행할 경우 !pip install tensorflow numpy matplotlib 명령어를 사용하여 라이브러리를 설치해야 합니다.