• 사용 방법 2가지 : 웹 / 데스크탑
    • 웹은 정말 불편함 / 데스크탑보다 기능이 제한적임 + 사용법이 미묘하게 조금씩 다 다름 (예를들면, 데이터 여러개를 웹상에서 보고싶으면 데이터 마트를 구성해야함. 데스크탑에서는 그냥 데이터 업데이트해서 올리면 해결되는 문제)
  • flow 생성방법
    • 엑셀데이터 : 데이터마트 생성(데이터 업로드) - 시멘틱모델 (=의미체계모델) - 리포트 - 대시보드 
    • 데이터브릭스 연동 :
      • 데이터브릭스에서 SQL ware house 생성 - connection details 에서 아래 두개 링크 복사 -패브릭 워크스페이스에서 dataflow gen2생성 - 아까 복사한 링크2개 복붙 - 불러올 데이터 가져오기 - 패브릭에서 레이크하우스 생성 - data flow gen2 연동 - 의미체계모델 만들기 - 보고서 생성
  • 실시간 업데이트 데이터 리프레쉬하는방법
    • 일단 데이터 올리는법은 크게 IMPORT/DEVICE QUERY 두가지 방법이 있음 
    • A) import (2가지 방법) - power bi desktop
      • 이미 만들어진 시멘틱 모델을 땡겨와서 power bi desktop 에서 연동 -> 수정사항이 있을경우 publish 로 업데이터 덮어씌우는 방식
        • 1) live connect
          • 웹상에 올라온 데이터를 직접 연동해서 씀
          • sql endpoint 방식보다는 좀 자유도가 들하다
          • 리프레쉬 버튼을 누르면 시멘틱모델이 변경된 사항이 반영된다.
        • 2) sql endpoint
          • 시멘틱 모델에 올라온 데이터를 통으로 로컬에 다운받은다음, 올릴때 데이터+보고서를 같이 올리는 방식
          • column 추가나 value 변환은 괜찮. 근데 column 이름/유형(중요)/삭제 시 에러가 나면서 publish 가 안된다
      • 리프레쉬를 반영하는방법
        • 1.원드라이브 파일을 사용하는법 (간단히 리프레쉬 버튼누르면됨)
        • 2. Share point team site(팀즈)
          • 팀즈에 파일 업로드 - 팀즈파일의 디테일에서 경로복사 - fabric power bi report 엑셀연결에서 url입력-테이블추가후 리포트생성
          • 데이터 리프레쉬는 기본으로 1시간단위로 세팅되어있다고함
          • 수동은 시멘틱 모델의 리프레쉬 버튼을 누르면됨
        • 3. 로컬파일 - 온프레미스 데이터 게이트웨이가 필요함. 그런데 private link 가 활성화된경우 이게 지원이 안됨
    • B) device query
      • 데이터 브릭스 데이터를 연동해서 쓸경우 설정을 보면 DEVICE QUERY라고 뜸
      • 몇시간에 한번 리프레쉬할건지 설정에서 설정해 줄 수 있다.
      • 리프레쉬 버튼누르면 업데이트된다. 리프레쉬 대상은 GEN2다 GEN2를 리프레쉬해야함.
  • 대시보드를 볼 수 있는 권한 설정
    • admin  - 테넌트 설정도 가능/워크스페이스 삭제 유일하게 가능/cu사용내역도 볼수 있음
    • member - 리포트 공유/수정/워크스페이스 수정 가능/멤버추가가능 (ppu나 pro 권한이 없어도 멤버 권한이 주어지면 수정이 가능함)
    • contributer - 리포트 보기/수정
    • viewer - 리포트 보기 가능
    • 앱배포 = 누구나 볼 수 있음 ( 단점은 딱 배포한 시점의 리포트가 보이기 때문에, 변화한 사항이 있으면 꼭 재배포 해줘야함, 앱 배포한 리포트가 삭제가 되어도 앱 링크에서는 잘보임)
더보기

Viewer - Can view all content in the workspace, but can't modify it.

Contributor - Can view and modify all content in the workspace.
Member - Can view, modify, and share all content in the workspace.
Admin - Can view, modify, share, and manage all content in the workspace, including managing permissions.

  • 일반적인 협업 방식
    • 시멘틱모델을 만들어놓고, 데스크탑에 연동해서 받아오기 publish 하는 식으로 플로우를 만들거나 덮어씌우는 방식으로 진행
    • 근데 만약 상대방이 변경된 내용을 퍼블리쉬하면 그걸 다시 받아서 수정해서 퍼블리쉬해야함 (import 방식으로 진행시 협업이 썩 용이하진 않음)
    • 웹은 한계점이 너무많아서 주로 데스트탑 파워비아이를 사용하는편
    • 앵간한 배경이나 디자인적인 요소를 향상시키고 싶을경우 피피티에서 배경을 싹 따와서 박고 그위에 그래프를 얹는식으로 진행하는게 빠름
  • 고질적인 문제점
    • 만약 한 리포트안에 파이차트가 두개있는데  A부문 에 있는 b,c,d,e항목을 볼때 나머지 파이차트는 A부문 100프로로 뜬다. 이쁘지가 않은데 이건 어쩔수 없다고함
    • 0.0001퍼센트같이 잘 보이지 않는 부분은 파이차트나 트리맵에서 잘 보이지도 않음. 숫자도 안나오는데 어케할수 있는 방법이 없다고함
    • 한달 사이로 다운받은 데스크탑 구성이 다름. 심지어 없는 그래프가 있음 ( 업데이트 주기가 굉장히 빠른편.....)
  • 파워비아이가 더 편한점 
    • 전처리를 엑셀단이나 파이썬/ sql로 수정하려면 복잡해지는 문제를 파워비아이 마트단에서 클릭클릭으로 간단히 해결되는 문제들도 있기 때문에 둘이 적당히 섞어 쓰면 좋다고 함
    • 보통 왕큰 원천 여러개랑 + 기준정보를 넣어서 연결연결 시켜서 사용한다고 함.
  • 꿀팁 꿀팁.....
    • 표안에 각각 다른 필터를 씌우고싶은데 필터설정이 컬럼별로 안되는거같다
      • 각 컬럼별로 dax문법으로 박아버리고 하나하나 선택해주면 된다.
    • 클릭시 변하게 하고싶다
      • 책갈피라는 기능이 있는데, 해당 페이지를 스냅샷으로 찍어서 이동하게끔 하는 방식임 (약간 노가다성)
  • DAX문법 예시
# 조건거는법
Q_sum = CALCULATE(SUM('Data'[매출]),'Data'[실적구분]='2024','Data'[조건1]="")
# 마이너스 세모표시로 바꾸는법
var result = ROUND(CALCULATE(SUM('Data'[매출]),'Data'[실적구분]='2024','Data'[조건1]=""),2)
var result2 = if(result<0,"△ "&CONVERT(-result,STRING),"+"&CONVERT(result,STRING))
return result2
# DAX끼리 빼기
yo = [@dax컬럼] - [@dax컬럼]
  • 추가 미적 변경
    • 행렬 - 행에서 위아래 폭 변경하고싶으면 (눈금-옵션-행안쪽 여백 늘리기)

Retrieval Augmented Generation (RAG) and Beyond: A ComprehensiveSurvey on How to Make your LLMs use External Data More Wisely

_5fa345fd048052006b2b74e9-Retrieval Augmented Generation (RAG) and Beyond_ A Comprehensive Survey on How to Make your LLMs use External Data More Wisely-031124-060947.pdf
1.15MB

Udemy 강의 내용 정리한것

【한글자막】 15일 완성 코스 - Power BI 완벽 부트캠프 | Udemy

- 강의는 POWER BI Desktop 기준으로 진행

- POWER BI Desktop 에서 만든걸 pbix 저장한다음, Fabric Power BI에 올려서 진행하는 방식으로 실습 진행함( Desktop 강의서가 더 많고, Fabric Power Bi에서 제약이 너무 많기 때문 )

- 조직계정외 개인개정으로 Fabric Power BI는 AZURE 무료계정만들기 => Microsoft 계정만들기로 진행가능

- Desktop-> Fabric Power BI 옮기려면 템플릿NONO POWER BI 문서로 저장해야함

  • DESKTOP에서 작업한것 save as -> one drive -> 맽밑에 pbix 이름지정 -> save 그런다음에 웹 fabric Power BI드가서 업로드-> 저장한 원드라이브 위치에 드가서 업로드한 파일 선택 하면 정상적으로 (데이터+대시보드)가 업데이트 됨

 

 

DAY2 : 데이터 전처리를 POWER BI 안에서 진행할수 있음

1. 데이터 수정은 Home - Transform data 눌러서 진행

- error 종종 뜰땐 텍스트로 바꾼다음 home - replae value 누른다음 NA 값을 없는값으로 만들어주기, 그리고 숫자로 바꿔주면 null로 바뀜

2. column 안에 너무 정보가 많을때 아래 잘 조합해서 쪼개기

  • Transform - split colum

       - by position 로 0,3,5 이렇게 나눠주면 TX - Montgomery 이게 3개 COLUMN으로 쪼개진다.

       - Split Column by Delimiter로 [ - ]를 넣어주면 2개 COLUMN으로 쪼개진다

  • Transform - Extract 

3. 앞뒤 공백 없애주기 : Column 마우스 우클릭 - Transform - Trim 앞뒤 공백 없애줌, Clean은 탭키 공백들도 없애줌

- 모든 컬럼 대문자로 시작하게 : 마우스 우클릭 - Transform - Capitalize Each Word

4. 소숫점 없애기

- 열 마우스 우클릭 - change type - whole number

5. 열 전체 합같은 연산하기

- Transform - Statistics - SUM 

열의 모든값을 합친 값만 output으로 내놓지 활용할거리가 하나도 없다.

6. 모든 열에 모두 100 더해주기, 모든열에 해당하는 값 연산,  cm을 인치로 바꾸기 (=단위 변환하기)

- Transform - Standard - Add - 100 ( 모든 열에 100을 더해줌)

- Transform - Standard - Multiply(곱셈) - 0.394(cm에서 인치로 변환하기위해 곱해줌) 

29,30 강의 다시듣기

8. 파이차트 주의할점 (앵간하면 비추함)

- 최악의 경우

  • 비슷비슷한값들의 경우 비교할때 파이차트를 사용하면 안됨 (심지어 비슷한 비율의 파이차트 두개를 보여준다? 최악)
  • 값이 너무 많은경우 비추함(항목이 2,3개일때만 사용하고, 항목이 5개를 초과할경우 절대 쓰지 말라고함) / 값이 너무 많은경우엔 세로 막대그래프를 권장함

- 파이차트를 권장하는 경우 / 사용 권장 방식

  • 파이차트는 전체에서 차지하는 비율(퍼센테이지)을 전시할때만 사용하라고 권장함. (총합 100퍼센트를 이루는것만 해당)
  • 과반수를 이루는것만 색깔 칠하기 등..
  • 파이차트에서 범례 쓰지말고 걍 원위에 항목 표시하기 (한눈에 안들어옴) 

- 디테일한 사용 방식

  • 범례 표위에 표시하는법 detail labels  에서 설정

DAY3 : 본격적인 시각화 툴 활용

- 두개 데이터 연결하기

  • 1. 1개 테이블뒤에 다른 테이블 붙이기
  • 2. append queries 로 새 테이블 만들기 (3개이상 연결)
  • if ) 연결하려는 두개 테이블의 column 명이 다를경우, a,b를 합쳐서 c를 만들었을경우 걍 a테이블로 돌아가서 컬럼명을 바꾸고 다시 c로 돌아와서 보면 알아서 고쳐져있음 (파워비아이의 장점!) 

- 데이터 타입 자동으로 바꾸기 ( 일일히 수동으로 변경하지 않아도 됨)

  • Transform - detect data type 

DAY4 : 데이터 변환

- 대시보드 필터 기능 (slicer)

  • 여러개 선택하고 싶으면 ctrl 누르고 선택하면 됨
  • ctrl 없이 여러개 누르고 싶으면 format - selection controls - Multi select with CTRL 활성화를 끄면됨

 

DAY5 : 대화형 시각화

- 오른쪽 메뉴 필터 slicer (그래프,페이지,전체등 범위선택가능)

  • filer on this visul 한정으로 topN기능 사용가능

- 여러페이지에서 동일 필터를 먹이는 방법 (sync slicers)

  • 1. slicer 를 복사 붙여넣기한다음 - 동기화하겠습니까? 묻는거에 YES
  • 2. slicer를 더블클릭하면 sync slicers 라고 오른쪽에 새로 뜨는 페이지를 클릭해서 어느 페이지에서 보여줄것인지 체크창에 체크표시하면 됨 (동기화와, slicer보임여부를 표시할 수 있음)

- 트리맵 시각화 (tree map)

  •  항목이 너무 많아서 막대그래프로 나타내도 스크롤이 줄질 않으면 트리맵을 추천 (위계적인 데이터에 추천)
    • 스크롤 없이 한눈에 보기 가능
    • 하지만 수치가 표시되는건 아니라 데이터라벨 추가해주면 좋음 format - 
    • detail 에 서브카테고리 컬럼을 추가해주면, 같은색안에 칸이 나뉘면서 그안의 서브카테고리들을 보여줌

- 드릴스루

  • 테이블에서 예를들어 0이상만 보여주고 싶을경우 Filters 에서 자세히 지정해주면 됨
  • 드릴스루로 더 자세히 봐줄 column을 지정해주면 드릴스루 메뉴가 뜸

- 말풍선 (마우스 커서 가져다 대면 뜨는거)

  • visualizations - build - tooltips에서 column들을 넣어주면 뜸
  • visualization - format - tooltip에서 툴팁 포맷도 디테일하게 설정해줄수가 있음 (안뜨게 OFF설정도 가능)

- 사용자 지정 열 ( 예를들어 너비,높이 Column을 가지고 넓이 Column을 새로이 만들어주는 작업을 의미함)

  • 데이터 transform - 연산해줄 컬럼을 눌르고 - STANDARD - Multiply (비교적 신기능으로 기존열과 새 열을 곱해서 열의 값을 바꾸어주는 기능)
  • 더 복잡한 작업을 해주려면 add column - custom column - M언어를 사용(m언어를 알필요는 없다고함, 인터페이스를 가지고 활용하면됨) - 열 선택해서 곱셈이면 * 이걸로 3개 열을 곱해주면 새로운 열이 생김. 

- 데이터양 줄이기 (활성화,비활성화 로드)

  • 해당 column이 대시보드에 나타나지 않도록 포함에서 제외하는 작업임.이작업을 하면 그 템플릿 다운받을때 (대시보드+데이터) 용량이 확준다
  • 전혀 쓰지않는 테이블이나 column의 경우 이작업을 통해 용량을 덜어냄 (데이터가 너무많으면 성능에 문제생길수있으니까)
  • Transform data - 테이블 마우스 우클릭 - enable load 클릭해서 선택해제 (해당 테이블을 사용하는 시각화는 에러가 생길것임) 
  • 비활성화되면 왼쪽에서 기울인 폰트로 보임

- 참조 VS 중복 (보고서의 성능) 64화

  • 일단 기존 테이블을 복제 (마우스 우클릭 - Duplicate)
  • 보통 참조용 테이블은 기존 테이블을 참조하게 함
  • 63,63 추가로 봐야할 필요가 있음

 

DAY6 : 고급 시각화

- Sort 방식 변경 (값기준, 월화수목.. 이런순서) + 조건부 열 순서 (66,67강의)

  • 1. x축이 monday tuesday... 이럴경우 높은값부터 나타날경우 차례대로 월화수목 이렇게 안뜨는 문제가 있음 (높은값부터, 낮은값부터 정렬되기 때문에 월화수목금토일 이케 안뜸)
  • 2. 그래프 맨 오른쪽 [...]  - Sort axis - 값이 아니라 다른 기준을 고르면 됨
  • 3. 하지만 가나다라, abcd방식으로 정렬되기 떄문에 역시 friday, monday, saturday... 이런식으로 뜨는 문제해결 : transform data - add column - conditional column 여기서 COLUMN 이름적고 OUTPUT 1-7 이케 적으면 순서해결
  • 4. 다시 돌아가서 column tools - 새로 더해준 기준대로 sort

- 예측 (선형차트)

  • Visualization - analysis 로 들어가면 Predict가 뜬다는데 안뜸. 그래서 그냥 PREDICT 그래프를 선택해줬음. 에러가남...

- 사용자 편의 드릴스루 (아이콘)-

 

 

 

< 추가 방법 >

- MATRIX 에서 interactive 하지않게 만들기

  • format - edit interactions - 없음 아이콘 선택하면 interactive하지 않게 표시

 

 

 

 

 

 

 
 

 
강의에서 하란대로 sql server express edition을 다운받아보았으나, 맥북이라 안됨 ^^
아래처럼 실습 환경 구축해서 진행함..

M2 맥북에서  AZURE SQL 실습환경 구축 (Data Studio+adventureworks.bak)

기본베이스는 https://learn.microsoft.com/ko-kr/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=data-studio#download-backup-files 이거 따라함 Azure Data Studio 설치하기 Azure SQL Server에서 [만들기] 눌러서

peanut159357.tistory.com

 

ㄴ or 를 대체해서 쓰는게 in / 100,200,300이 아닌경우 를 솎아낼때 쓰는용도로 유용 (실무에서 많이 쓰임)

 

-- LEFT(X1,X2) / RIGHT(X1,X2)
SELECT [ModifiedData] LEFT([ModifiedData,10]) AS D_DATE, RIGHT([ModifiedData,12]) AS D_TIME FROM [Sales][Customer]

문자열을 왼쪽에서 몇자까지만 보여주겠다 (왼쪽은 날짜만 나오게, 오른쪽은 시간만 나오게 조정 (as는 새로운 컬럼으로 만들어서 보여줌)

--SUBSTRING(x1,x2,x3) x1는 대상문자열, x2는 시작, x3은 종료
SELECT SUBSTRING('MS SQL DATABASE MANAGEMENT STUDIO',8,8) AS D_STRING

위에서 너무 기니까 LEFT+RIGHT를 합친게 SUBSTRING

-- len()
SELECT LEN([AccountNumber]) FROM [Sales].[Customer]
-- COLUMN별로 몇개 길이를 가지고 있는지 출력해준다
--REPLACE(x1,x2,x3) x1대사문자,x2지칭하는문자열, x3바꿔줄문자열
SELECT 'SQL IS SO DIFFICULT', REPLACE('SQL IS SO DIFFICULT', 'DIFFICULT','EASY') AS D_REP
-- SYSDATETIME(), GETDATE()
SELECT GETDATE() AS T_DATE
-- YEAR(X1), MONTH(X1), DAY(X1)
YEAR(GETDATE()) AS T_Y, MONTH(GETDATE()) AS T_M,DAY(GETDATE()) AS T_D
-- DATEPART(x1,x2)
DATEPART(YY.GETDATE()) AS T_Y, DATEPART(MM.GETDATE()) AS T_M, 
DATEPART(HH.GETDATE()) AS T_H, DATEPART(II.GETDATE()) AS T_I, DATEPART(SS.GETDATE()) AS T_S,

SELECT * FROM [Purchasing].[PurchaseOrderDetail] 
WHERE DATEPART(YY,ModifiedDate)=2014 AND  DATEPART(MM,ModifiedDate)=1
-- DATEDIFF(x1,x2,x3) 두개사이의 간격 구하는것
SELET DATEDIFF(YY, '2020-01-01', GETDATE()) AS D_Y
-- OUTPUT = 2
SELECT DATEDIFF(YY, BirthDate, GETDATE()) AS D_AGE FROM [HumanResource].[Employee]
-- 위의 예제는 직원들 나이구하는것
-- DATEADD(x1,x2,x3) x1대상, x2가 -3이면 3년을 뺴라는소리, x3은 now
SELECT DATEPART(W, DATEADD(DD,1000, '2020-01-01')) AS A_W 
-- 위에는 요일을 출력하라는 뜻으로 6이 출력됨 (월요일이 1)

<집계처리>

- STDEV 표준편차
- VAR 분산
- SUM 누적합계
- AVG 평균
- COUNT 총개수

SELECT VendorID, Count(VendorID) AS CC
FROM [Purchasing].[PurchaseOrderHeadr]
WHERE VendorID>=1500
GROUP BY VendorID
ORDER BY COUNT(VenderID) DESC
-- 순서에 유념
SELECT DATEPART(YY, OrderDate) AS A_Y, COUNT(DATEPART(YY, OrderDate)) AS CC
FROM [Purchasing].[PurchaseOrderHeader]
GROUP BY DATEPART(YY, OrderDate)
-- 년도만 보고, 년도별로 그룹핑해서 몇개인지 알아보려는 용도

-- SELECT Color, ListPrice FROM [Production].[Product]
-- WHERE Color IS NOT NULL
-- GROUP BY Color

SELECT Color, AVG(ListPrice) AS A_V FROM [Production].[Product]
WHERE Color IS NOT NULL
GROUP BY Color
HAVING AVG(ListPrice)>10

중요) 집계가 이뤄지고난 후에 값들은 having 을 통해 지정되어야함

IN-LINE VEIW

 

** 인라인 뷰
-- SELECT Color, AVG(ListPrice) AS A_V FROM [Production].[Product]
-- WHERE Color IS NOT NULL
-- GROUP BY Color
-- HAVING AVG(ListPrice)>10 
-- 이걸 아래 인라인뷰를 사용해서 똑같이 만들어보자

SELECT * FROM
(SELECT Color, AVG(ListPrice) AS A_V FROM [Production].[Product]
WHERE Color IS NOT NULL
GROUP BY Color) AS TEMP_T
WHERE A_V>10

SUBQEURY

 

OUTER JOIN

**인라인 사용

INNER JOIN

'<문법>' 카테고리의 다른 글

리눅스 명령어 목록  (0) 2021.04.17

< 뻘짓.. 찐 실행은 살짝 뒤에서부터..>

 

원래 databricks에서 실행하고 싶어서 이모저모 찾아봤는데, 아무리 찾아봐도 databricks에 bak 데이터를 업로드하는 튜토리얼이 전혀 보이지 않았다... (혹시 있으면 댓글로 알려주시면 감사감사 왕감사..) 그래서 azure data studio를 제일 많이 쓰는거 같길래 설치함

 

기본베이스는 https://learn.microsoft.com/ko-kr/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=data-studio#download-backup-files 이거 따라함

 

Azure Data Studio 설치하기

 

Azure SQL Server에서 [만들기] 눌러서 새로 만들어주기

 

Azure 계정이랑 연결하기 (왼쪽 아이콘중 맨위에 connection 누른다음 뒤적거리다보면 앞에서 새로 만들어준게 나옴. 그거 클릭하면 됨)

ㄴ그런데 여기서 100% 에러남 ->  네트워크 설정 공용 네트워크 허용으로 바꿔주기

 

(예외 규칙 새로 안만들어줘도 새로생성한 sqlserver 네트워킹 설정 들가서 그냥 공용엑세스 메뉴에서 사용안함 -> 선택한 네트워크로 저장해주고, azure sql data studio 들어가서 connection 누르니까 지가 알아서 방화벽 만들어서 접속됨)

 

 

문제없이 진행되었을경우, 튜토리얼대로 manage버튼 안눌르고, 빨간 박스친것이 보이는데 클릭하면 된다.

 

왜 preview...? azure 튜토리얼은 뭔.. 맞는게 없는거 같은데 알아서 감으로 하쇼 이런건가?

 

 

(찐실행하기 전에 뻘짓으로 만들어준 sql server삭제하고.. 진행하기)

 

< 찐 실행은 여기서부터 >

 

아 저걸 눌러도 계속 에러가 뜸. 도커 설치는 필수였나보다....

 

https://debugsolutions.wordpress.com/2022/05/03/how-to-restore-a-database-on-azure-data-studio-for-mac-with-docker/ 이거 똑같이 따라서 도커 설치하고 data studio 재 연결하면됨

 

**error) docker run –cap-add SYS_PTRACE -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=Password.1' -p 1433:1433 –name azuresqledge -d mcr.microsoft.com/azure-sql-edge 이 실행 에러나는데 docker run --cap-add SYS_PTRACE -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=StrongPass030424!' -p 1433:1433 --name azuresqledge --restart unless-stopped -d mcr.microsoft.com/azure-sql-edge 이걸로 바꿔서 실행하면 성공~ (from gpt)

 

되었당..!!

 

**error) 파일 옮길때 에러나면 이렇게 '' 이거 따옴표 없애면 됨. docker cp /Users/yoonseo/downloads/AdventureWorks2019.bak azuresqledge:/var/opt/mssql/backup

 

 

야호~~~!!!!!!!

1. Large Language Models(LLMs) on Tabular Data: Prediction, Generation, and Understanding - A Survey

더보기

[중요내용 정리]

 

TABULAR  특징 

  1. 데이터의 다양성 ( 이진,수치형,텍스트같은 다양한 유형포함) 
  2. 불균형한 레이블과 없는값들이 많을수도 
  3. 전처리 필요성 
  4. 컨텍스트기반의 상호연결(예를들어 나이,교육수준,음주는 연결된) 
  5. 순서 무관 
  6. 사전지식의 부재 - 종종 이미지나 오디오데이터는 사전지식이 필요하다 

 

전통적인 tabular data과 딥러닝 활용 

  • Gradient Boosted Decision Trees 
  • 부스팅앙상블 
    • 한계점1 : 범주형특징같은것에 민감할수있으며암묵적 학습 수행이 가능 
    • 한계점2 : 시계열 데이터의 경우 처리하기 적합하지않다 
    • 한계점3 : 전체 분포가 골고루지 않을경우 일반화하기 어려울수 있다 
  • CNN방법론은 여러가지로 발전 
    • 데이터변환 
    • 미분가능트리 
    • 어텐션기반(TABNET) 
    • 정규화 
  • 여러가지 시도가 있었음에도 XGBoostLightGBMCatBoost 등을 포함한 GBDT 알고리즘 들이 여전히 우수함 
    • 베이지안 네트워크같은 딥러닝 적급낭버보가 LLM같은 생성모델의 발전 
  • LLM의 가장 전통적인 건 QA 
    • QA : TAPAS (Herzig et al., 2020), TABERT (Yin et al., 2020b), TURL (Deng et al., 2022a), TUTA (Wang et al., 2021), TABBIE (Iida et al., 2021) 

 

LLM의 간단설명(여기선 대형 PLM이라고도 부름) 

  • 모델은 텍스트 말뭉치의 일반적인 문법 및 의미적 이해를 얻은 후, 과제별 목적에 맞추어 훈련됩니다 
  • 이전 연구에서는 표형식 데이터의 표현 학습을 위해 LM을 사용하였으나 이는 제한적이었습니다향후 연구에서는 표 데이터를 텍스트로 변환하여 PLM을 활용하여 의미 정보와 헤더 정보를 고려한 문맥적 표현을 학습하는 방법을 제안하였습니다이를 통해 크로스 테이블 학습과 특성 열의 순열 불변성을 지니는 모델을 구축하는 것이 가능해졌습니다. 

 

현재 LLM의 잠재력에 대해 계속 탐구하고 있음. 

  1. 딥 러닝 방법은 초기 훈련에서 사용되지 않은 데이터셋에서는 최적의 성능을 보이지 않는 경우가 많기 때문에사전 훈련과 세밀 조정 패러다임을 활용한 전이 학습이 매우 유망합니다. (= 파인튜닝) 
  2. 표 데이터를 LLM에서 읽을 수 있는 자연 언어로 변환함으로써고차원 범주형 데이터의 one-hot 인코딩에 따른 차원의 저주(curse of dimensionality)를 피할 수 있습니다. (테뷸러 데이터를 txt로 변환해서 고차원문제를 해결) 
  3. CoT를 통한 단계적인 추론과 같은 신생 능력은 LM을 언어 모델링에서 보다 일반적인 작업 해결 도구로 변형시켰습니다LLM의 신생 능력이 표 데이터 모델링에서 얼마나 작동하는지 테스트하기 위해 더 많은 연구가 필요합니다.(cot 단계적 구성성단계적 추론은 다양한 작업에 적용할수있게 해준다) 

 

Contribtion 

  1. LLM을 타블로 데이터 예측타블로 데이터 합성타블로 데이터 질문 답변테이블 이해와 같은 분야들을 세분화하여 분류 
  2. 타블로 데이터에 LLM을 적용한 방법을 평가하는 다양한 측정 항목에 대한 현황과 분류법을 조사 (한마디로 정확도 측정 방법을 조사) 
  3. 많이들 사용되는데이터셋에 대한 현황과 분류법을 조사 
  4. Table data + llm 의 현황과 분류법 
  5. 도전과제와 개요 

 

Key techniques for LLMs’ applications on tabular data 

  • 직렬화 
    • Tabular -> text (text/json/xml...) 
      • 표를 쉼표같은 구분기호로 변환도 가능 
      • 마크다운 형식으로 변환도 가능 
  • Embedding based (직렬화 한걸 벡터화) 
    • Bert를 기반으로 하는 다양한 테이블 인코더들이 있다. 
  • 그래프기반,트리기반 데이터구조로 변환 
    • 하지만 직렬화를 해줘야 한다고  
  • 데이터 형식이 정확도에 매우 민감 
    • 예를 들어DFLoader와 JSON 형식이 테이블 변환 작업에 더 적합하다는 연구 결과와 HTML 또는 XML 테이블 형식이 GPT 모델에서 더 잘 이해되는 것을 보여주는 연구 결과가 있습니다 
  • 추가정보 
    • 직렬화+임베딩을 한번에 하는 방법들도 있다고함 (표에대한설명을 문장으로생성) 
      • LMs (Fine-tuned BLOOM on ToTTo (Parikh et al., 2020b), T0++ (Sanh et al., 2022), GPT-3 (Ouyang et al., 2022)) 
    • Few-shot분류시 전통적인 리스트와 텍스트 템플릿이 llm 직렬화보다 성능이 더 좋았다고함 
    • 복잡하고 큰 LLM일수록 성능이좋다 

 

Table 조작(고려해야할 사항) 

  • LLM모델은 인풋시 텍스트 제한이 있다. 2048토큰까지 처리가능. Llama2는 4048토큰지원. 만약 테이블이 너무 크면부족할수가있다 
  • 길이는 문제 없어도 긴문장을 처리시에 비효율적이다. ' 
    • 1000토큰이상일경우 GPT3에서 성능저하를 확인 
  • 긴 프롬프트는 LLM 기반에서 너무 비싸다 

 

Prompt engineering 

  • 프롬프트 = llm에 입력되는 텍스트 
    • 가장간단한 형식은 문자열 
    • IN-CONTEXT LEARNING = 유사한예를 통합하여 LLM이 원하는 결과를 이해하는데 도움이 되는걸 의미 
      • In-Context Learning은 특정한 맥락(context) 내에서 필요한 정보를 바탕으로 학습하는 방식을 말합니다이는 기존의 대규모 데이터 세트를 통해 사전 학습(pre-training)하는 과정 없이제한된 정보 내에서 바로 학습하고 적용할 수 있는 방식을 의미합니다. 
      • 프롬프트 엔지니어링을 통해 이루어진다. 
      • 사용자가 프롬프트를 입력하면 gpt3는 텍스트를 분석해서 컨텍스트를 이해하고 관련출력을 생성하는것사용자가 오늘 기분이 슬퍼 라는 프롬프트를 입력하면 gpt3가 그것참 유감이군요 제가 도와드릴일이 있을까요 라는 출력을 생성하는걸 의미합니다. 
      • 한마디로 프롬프트의 내용만으로 하고자하는 task를 수행하는것을 말한다promt안의 맥락적의미(in context)를 이해하고 답변을 생성하는것프리트레이닝이나 파인튜닝같은 작업업이 별도의 학습과정이 존재하지않는다 
        • Zero shot 
          • Prompt: 빨간 사과가 영어로 뭐야? 
          • GPT: "Red Apple" 
        • One shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는? 
          • GPT: 노란 바나나는 "yellow 바나나"입니다. 
        • Few shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는 yellow 바나나야그럼 노란 사과는? 
          • GPT: 노란 사과는 "yellow 사과"입니다. 
      • 예시는 CoT, SC 임 
        • 전자는 단계별 사고로 분해해서 더 나은 추론을 만들어내는 전략 
        • 다양한 사고방식을 허용한다는 직관을 바탕으로함 

 

  • Retrieval-augmented generation(rag / 검색증강생성) 
    • Llm모델의 출력을 최적화 하여 응답을 생성하기 전에  데이터 소스 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 프로세스 
    • 이런 지식소스를 참조하여 다양한 환경에서 사용자 질문에 답변이 가능한 봇을 만드는것 
    • 1)검색모듈로 주어진 검색어나 질의에 따라 정보검색하고 문맥추출  
    • 2) 생성모듈로 앞서서 검색된정보들을 바탕으로 문장을 생성함 
  • ROLE-PLAY 
    •  예를 들어, Zhao 등 (2023a)은 프롬프트 "통계 분석 전문가로 가정해보세요."로 실험을 진행했다고함 

 

 

 

Preprocessing (테뷸러 데이터를 활용하여 데이터 직렬화 하는 방법) 

  • LIFT (Dinh et al., 2022)는 초기 노력 중 하나로, "열 이름은 값(Value)입니다"와 같은 자연어 문장 또는 "col1 = val1, col2 = val2, ..."와 같은 여러 방정식과 같은 직렬화 방법을 시도 
  • 동일한 결론은 TabLLM (Hegselmann et al., 2023)에서도 확인되었으며그들은 9가지 다른 직렬화 방법을 평가 
    • 텍스트로 구성된 모든 피처의 열거가 가장 우수한 성능을 발휘한다고 함(3번째 논문) 
  • TABLET논문방법을 사용하면 F1스코어가 매우 높게 오른다는걸 확인 
  • 스키마 기반의 프롬프트 엔지니어링 데이터셋의 배경 정보작업 설명요약 및 예시 데이터 포인트를 포함한다고 함 
  • Summary Boosting (Manikandan et al., 2023)은 데이터+메타데이터를 텍스트 프롬프트로 직렬화하여 요약을 생성 
  • Serilize-LM (Jaitly et al., 2023)는 도메인 특정 데이터셋에서 LLM 성능을 향상시키기 위해 3가지 혁신적인 직렬화 기술을 소개 
    • 차량 분류를 예로 들면제조사색상 및 차체 유형과 같은 속성이 이제 단일한 더 풍부한 문장으로 결합 
    • 또한, 가장 관련성이 높은 피처를 식별하기 위해 공분산을 활용하고, 해당 피처를 중요하다고 라벨링하거나 가장 중요한 피처를 설명하는 문장을 추가 (데이터의 경중을 판단한다는 뜻 같다) 
    • 마지막으로테이블 데이터를 LaTeX 코드 형식으로 변환 
  • UniPredict (Wang et al., 2023a)는 임의의 입력 M을 대상 설명과 피처의 의미론적 설명으로 통합하여 메타데이터를 형식화 
  • …. 

 

 

Time Series Forecasting (테이블 데이터 중에서도 시계열 예측 !!!!!!) 

  • ZeroTS (Gruver et al., 2023)은 GPT-3 (Brown et al., 2020)와 LLaMA-70B Touvron et al. (2023a)와 같은 LLM을 직접 시계열 예측에 사용 
    • 이 연구는 평균 절대 오차(MAE), 스케일 MAE 및 연속된 순위 확률 점수(CRPS)를 사용하여 모델을 평가하며LLM은 간단한 규칙 기반의 완성을 선호하고 반복 및 추세를 캡처하는 경향이 있다고 언급 
      • => llm은 시계열 예측에도 매우 효율적이다. 

 

  • Finetuning시 일반적으로현재 LLaMa가 가장 일반적으로 사용되는 모델이며, fine-tuning에는 soft prompt가 적합한 접근 방식이라고 함 
  • 메트릭으로는 MAE가 가장 일반적인 메트릭 

 

 

 

LLMs for tabular data generation (Tabular 데이터를 보완하는 새로운 방법론을 탐구-뉴데이터를 생성해서 활용) 

  • tabular데이터를 보완하는 새로운 방법론을 탐구 
  • Llm을 활용해서 새로운 tabular데이터를 생성하고 활용할 수 있는 방법들을 연구 
    • 한마디로 llm을 활용해서 데이터를 생성해서 활용한다 

 

  • Borisov et al. (2023b)은 원본 tabular 데이터의 특성을 가진 합성 샘플을 생성하기 위해 GReaT11 (Generation of Realistic Tabular data) 제안. GReaT 데이터 파이프라인은 문장 직렬화 방법을 사용하여 tabular 데이터를 의미 있는 텍스트로 변환하는 텍스트 인코딩 단계와 관련. 이후에는 GPT-2 또는 GPT-2 distill 모델을 미세 조정하는 과정이 이어짐.  
  • REaLTabFormer (Solatorio & Dupriez, 2023)은 GReaT를 확장하여 비관계형 및 관계형 타블러 데이터를 생성 
  • 등등.... 

++ figure4  참조

  • 이러한 합성 데이터의 평가방법 4가지 
    1. 저차원 통계열별 밀도와 열 간의 상관관계를 평가하여 개별 열의 분포와 열 간의 관계를 파악 (열별 데이터분포를 살펴봄으로써 다양성과 일관성을 평가한다예를들면 열값이 균일하게 분포되어있는지확인가능. 또 상관관계를 통해서 음의 상관관계이니지 직선적인 상관관계인지 등등 파악가능) 
    2. 고차원 측정합성 데이터의 전체적인 신뢰성과 다양성을 측정하는 지표를 사용합니다. (=다양한 관점에서데이터품질과 다양성을 측정예를들어 실제데이터와 얼마나 유사한가 같은 지표) 
    3. 개인 정보 보호원본 데이터의 개인 정보 보호 수준을 평가하기 위해 최근접 레코드와의 거리를 계산하는 지표를 사용합니다.(개인식별 가능성을 평가함원본데이터랑 유사도를 평가해서 유사할수록 개인정보 식별 가능서이 높아지고유사도가 낮을수록 개인정보수준이 높아진다)) 
    4. 하위 작업 성능합성 데이터를 사용하여 학습한 모델이 실제 데이터에서 얼마나 잘 작동하는지 평가합니다. 

 

 

 

LLMs for table understanding 

  • TABLE QA  
  • Table and Conversation QA = QA인데 테이블만 사용하는게 아니라 다른 형식의 정보들도 같이 사용하여 대화를 진행 
  • Table Classification = 테이블을 종류별로 분류하는것 
  • Text2SQL = sql 생성 
  • Table NLG = 원본 테이블에 대한 설명을 생성 
  • Table NLI = 테이블안의 관계에 대해 분석(2019에 많이 팔린 상품은 무엇) 
  • Domain Specific = 영역별로 특화항공업계는  AIT-QA (Katsis et al., 2022)를 사용하는 것을 권장금융 관련 테이블 질문 답변 작업에는 TAT-QA (Zhu et al., 2021a)를 사용하는 것을 추천대략적으로 업계별로 추천하는것이 다르다는것으로 이해 
  • Pretraining = 테이블+영어문맥설명으로 프리트레이닝하면 테이블 이해해 더 좋은 결과를 볼수 있다라고 함 

 

 

General ability of LLMs in QA 

 

  • Numerical QA = 수학 추론을 필요로 하는 질문(American Express의 평균 거래 별 결제량은 얼마입니까?) 
  • Text2SQL =  Liu et al. (2023c)은 세 가지 유형의 키워드를 식별하는 질문 매처를 설계: 1) 열 이름과 관련된 용어, 2) 제한과 관련된 구절(예: "상위 10개"), 3) 알고리즘 또는 모듈 키워드. 
  • Impact of model size on performance=WebTableQuestions에서 6.7B 대 175B GPT-3 모델을 비교할 때, 작은 모델은 더 큰 모델의 점수의 절반만 달성 
  • Finetuning or No finetuningLLMs(>70B 파라미터)를 파인튜닝하는 것에는 매우 제한적인 연구가 진행 

 

 

QA 관련 논문들 

  • Chain-of-command (CoC)-사용자입력을 중간명령작업의 순서열로 변환
  • Deng et al. (2022b)는 QA 작업을 세 가지 하위 작업으로 분할 
    • 불확실성을 명확히 하기 위해 질문을 할 것인지를 결정하는 Clarification Need Prediction (CNP)
    • 명확히 하기 위해 질문을 생성하는 Clarification Question Generation (CQG)
    • 질문에 대한 명확히가 필요하지 않은 경우 바로 답변을 생성하는 Conversational Question Answering (CQA)
  • 검색능력도 중요함. 검색능력은 아래와같이 두가지 유형으로 나뉨
    • 질문과 관련된 정보를 찾기 ( 예를들어 무슨열의 무슨행의 값을 구해줘(
    • 추가정보와 예제를 얻는것
  • 데이터 메인테이블 관련
    • Zhao et al. (2023d)는 최상위-n개의 가장 관련성이 높은 문서를 반환하는 검색 모듈 (retriever module)의 성능 향상이 수치적 QA에서 최종 정확도를 일관되게 향상시킨다는 것을 관찰
    • . Sui et al. (2023c)는 여러 개의 테이블 샘플링 방법 (행과 열)과 토큰 제한 매개변수를 기반으로 한 테이블 패킹을 탐구(질문과 가장 의미적으로 유사한 행을 검색)
    •  Dong et al. (2023)는 SC(Self-consistency, 또다른논문이다)를 사용하여 질문과 관련성에 따라 테이블을 순위 매김하기 위해 ChatGPT를 사용. 그 결과 10개세트의 검색결과를 생성한다음, 가장 자주보이는 세트를 선택. 이때도 SC방법이 사용되었다고함. 
    •  cTBLS Sundar & Heck (2023)는 검색된 테이블 정보에 기반한 대화 응답을 검색하고 생성하기 위한 세 단계 아키텍처를 설계함
      • RoBERTa (Liu et al., 2019)에서 유도된 양방향 인코더 기반의 Dense Table Retrieval (DTR) 모델을 사용해서 연관성이 가장높은 테이블을 식별(인코더만 사용한다)
      • 두 번째 단계에서 트리플릿 손실을 사용하여 행을 순위 매기기 위한 Coarse System State Tracking 시스템을 사용 (??)
      • 마지막으로, GPT-3.5는 그룹화된 지식 원본을 기준으로 한 쿼리와 관련성이 가장 높은 셀을 조건으로 하는 추가 질문에 대한 자연어 응답을 생성
      • INPUT = 질의 기록, 순위 매김된 지식 원본 및 답변해야 할 질문이 포함된 프롬프트가 입력으로 제공
    • . Zhao et al. (2023d)은 OpenAI의 Ada Embedding4과 Contriever (Izacard et al., 2022)를 검색기로 사용하고 BM25 (Robertson et al., 1995)를 희소 검색기로 사용. 여기서 말하는 검색기란 가장 관련성이 높은 텍스트랑 테이블을 추출하는데 도움을 주는것. 이 추출된 정보는 질문에 대한 입력 컨텍스트로 제공됩니다.
  • 예제선별관련
    • Gao et al. (2023)는 1) 무작위로 K개 선택 2) 질문의 유사성을 선택(유사성기준은 유클리드거리같은 사전에 정의된 기준을 사용) 3) 마스킹된 질문 유사성을 선택한다.(=질문과 예제간의 유사성을 평가해서 예제를 선택하는것) 4) 대상 SQL 쿼리 s∗와 유사한 k개의 예제를 선택.

 

Multi-turn tasks

LLM을 반복적으로 호출하는 파이프라인을 설계

3가지 카테고리로 분류된다

(1) 어려운 작업을 처리 가능한 하위 작업으로 분해하기 위해 (너무 복잡한 요청을 작은 여러개 작업으로 나눔)

  • Suiet al. (2023b)은 하류 테이블 추론을 개선하기 위해 두 단계의 self-augmented prompting approach를 제안. 첫 번째로 프롬프트를 사용하여 LLM에게 테이블에 대한 중간 출력을 생성하도록 요청한 다음, 응답을 두 번째 프롬프트로 통합하여 하류 작업의 최종 답변을 요청한다.
  • Ye et al.(2023b)은 또한 대량의 테이블을 작은 테이블로 분해하고 복잡한 질문을 텍스트 추론을 위해 단순한 하위 질문들로 변환하도록 LLM에게 안내
  •  Liu 등(2023e)의 경우, 상징적인 CoT 추론 경로를 촉진하기 위해, 모델이 명령을 실행하고 데이터를 처리하며 결과를 검토할 수 있는 Python 셸과 상호작용하도록 허용  

(2) 새로운 사용자 입력에 기반하여 모델 출력을 업데이트하기 위해

  •  SParC의 경우, Spider (Yu 등, 2018b)를 기반으로 연이어 따르는 질문을 설계

(3) 특정 제약 조건을 해결하거나 오류를 수정하기 위해

  • Zhao 등(2023a)은 테이블이 API 입력 제한을 초과하는 경우 다중 턴 프롬프트를 사용하여 이를 해결. 잘못된 부분이 생성되었을 경우 잘못된 경우를 LLM을 되돌려주는 반복적인 과정이 도움이 될수 있다고함.

 

 

아웃풋 평가 방식

  • F1이 일반적이긴함
  • ROUGE
  • BLEU
  • 시각화..

 

 

한계점과 미래방안

  • Bias and fairness llm의 내재적인 편향 완화
  • Hallucination 실제가 아닌값을 생성할 위험 (의료계쪽에서는 치명적)
  • Numerical representation 숫자는 임베딩이 꼭 필요
  • Categorical representation 컨텍스트 제한 초과시 데이터 일부가 날라가서 성능에 부정적이어짐. 이를 커버할수있는 인코딩방식이 필요
  • Standard benchmark 너무 다양하기 때문에 표준화된 벤치마크의 필요성
  • Model interpretability 데이터 이해능력의 탐구
  • Easy to use 대부분 데이터 직렬화가 필요해서 모델 엑세스가 쉽지않음. 다른사람들이 사용하기 쉬워야함.(자동전처리나 직렬화를 통합시킨다면 훨씬 쉬울것)
  • Fine-tuning strategy design llm모델의 적합한 모델과 학습전략
  • Model grafting 특화된 인코더를 사용해서 비문자 데이터를 매핑..한마디로 텍스트가 아닌 다른 유형의 데이터를 모델이 자체적으로 인코딩할수있다..

[중요내용 정리]

 

TABULAR  특징 

  1. 데이터의 다양성 ( 이진,수치형,텍스트같은 다양한 유형포함) 
  2. 불균형한 레이블과 없는값들이 많을수도 
  3. 전처리 필요성 
  4. 컨텍스트기반의 상호연결(예를들어 나이,교육수준,음주는 연결된) 
  5. 순서 무관 
  6. 사전지식의 부재 - 종종 이미지나 오디오데이터는 사전지식이 필요하다 

 

전통적인 tabular data과 딥러닝 활용 

  • Gradient Boosted Decision Trees 
  • 부스팅앙상블 
    • 한계점1 : 범주형특징같은것에 민감할수있으며암묵적 학습 수행이 가능 
    • 한계점2 : 시계열 데이터의 경우 처리하기 적합하지않다 
    • 한계점3 : 전체 분포가 골고루지 않을경우 일반화하기 어려울수 있다 
  • CNN방법론은 여러가지로 발전 
    • 데이터변환 
    • 미분가능트리 
    • 어텐션기반(TABNET) 
    • 정규화 
  • 여러가지 시도가 있었음에도 XGBoostLightGBMCatBoost 등을 포함한 GBDT 알고리즘 들이 여전히 우수함 
    • 베이지안 네트워크같은 딥러닝 적급낭버보가 LLM같은 생성모델의 발전 
  • LLM의 가장 전통적인 건 QA 
    • QA : TAPAS (Herzig et al., 2020), TABERT (Yin et al., 2020b), TURL (Deng et al., 2022a), TUTA (Wang et al., 2021), TABBIE (Iida et al., 2021) 

 

LLM의 간단설명(여기선 대형 PLM이라고도 부름) 

  • 모델은 텍스트 말뭉치의 일반적인 문법 및 의미적 이해를 얻은 후, 과제별 목적에 맞추어 훈련됩니다 
  • 이전 연구에서는 표형식 데이터의 표현 학습을 위해 LM을 사용하였으나 이는 제한적이었습니다향후 연구에서는 표 데이터를 텍스트로 변환하여 PLM을 활용하여 의미 정보와 헤더 정보를 고려한 문맥적 표현을 학습하는 방법을 제안하였습니다이를 통해 크로스 테이블 학습과 특성 열의 순열 불변성을 지니는 모델을 구축하는 것이 가능해졌습니다. 

 

현재 LLM의 잠재력에 대해 계속 탐구하고 있음. 

  1. 딥 러닝 방법은 초기 훈련에서 사용되지 않은 데이터셋에서는 최적의 성능을 보이지 않는 경우가 많기 때문에사전 훈련과 세밀 조정 패러다임을 활용한 전이 학습이 매우 유망합니다. (= 파인튜닝) 
  2. 표 데이터를 LLM에서 읽을 수 있는 자연 언어로 변환함으로써고차원 범주형 데이터의 one-hot 인코딩에 따른 차원의 저주(curse of dimensionality)를 피할 수 있습니다. (테뷸러 데이터를 txt로 변환해서 고차원문제를 해결) 
  3. CoT를 통한 단계적인 추론과 같은 신생 능력은 LM을 언어 모델링에서 보다 일반적인 작업 해결 도구로 변형시켰습니다LLM의 신생 능력이 표 데이터 모델링에서 얼마나 작동하는지 테스트하기 위해 더 많은 연구가 필요합니다.(cot 단계적 구성성단계적 추론은 다양한 작업에 적용할수있게 해준다) 

 

Contribtion 

  1. LLM을 타블로 데이터 예측타블로 데이터 합성타블로 데이터 질문 답변테이블 이해와 같은 분야들을 세분화하여 분류 
  2. 타블로 데이터에 LLM을 적용한 방법을 평가하는 다양한 측정 항목에 대한 현황과 분류법을 조사 (한마디로 정확도 측정 방법을 조사) 
  3. 많이들 사용되는데이터셋에 대한 현황과 분류법을 조사 
  4. Table data + llm 의 현황과 분류법 
  5. 도전과제와 개요 

 

Key techniques for LLMs’ applications on tabular data 

  • 직렬화 
    • Tabular -> text (text/json/xml...) 
      • 표를 쉼표같은 구분기호로 변환도 가능 
      • 마크다운 형식으로 변환도 가능 
  • Embedding based (직렬화 한걸 벡터화) 
    • Bert를 기반으로 하는 다양한 테이블 인코더들이 있다. 
  • 그래프기반,트리기반 데이터구조로 변환 
    • 하지만 직렬화를 해줘야 한다고  
  • 데이터 형식이 정확도에 매우 민감 
    • 예를 들어DFLoader와 JSON 형식이 테이블 변환 작업에 더 적합하다는 연구 결과와 HTML 또는 XML 테이블 형식이 GPT 모델에서 더 잘 이해되는 것을 보여주는 연구 결과가 있습니다 
  • 추가정보 
    • 직렬화+임베딩을 한번에 하는 방법들도 있다고함 (표에대한설명을 문장으로생성) 
      • LMs (Fine-tuned BLOOM on ToTTo (Parikh et al., 2020b), T0++ (Sanh et al., 2022), GPT-3 (Ouyang et al., 2022)) 
    • Few-shot분류시 전통적인 리스트와 텍스트 템플릿이 llm 직렬화보다 성능이 더 좋았다고함 
    • 복잡하고 큰 LLM일수록 성능이좋다 

 

Table 조작(고려해야할 사항) 

  • LLM모델은 인풋시 텍스트 제한이 있다. 2048토큰까지 처리가능. Llama2는 4048토큰지원. 만약 테이블이 너무 크면부족할수가있다 
  • 길이는 문제 없어도 긴문장을 처리시에 비효율적이다. ' 
    • 1000토큰이상일경우 GPT3에서 성능저하를 확인 
  • 긴 프롬프트는 LLM 기반에서 너무 비싸다 

 

Prompt engineering 

  • 프롬프트 = llm에 입력되는 텍스트 
    • 가장간단한 형식은 문자열 
    • IN-CONTEXT LEARNING = 유사한예를 통합하여 LLM이 원하는 결과를 이해하는데 도움이 되는걸 의미 
      • In-Context Learning은 특정한 맥락(context) 내에서 필요한 정보를 바탕으로 학습하는 방식을 말합니다이는 기존의 대규모 데이터 세트를 통해 사전 학습(pre-training)하는 과정 없이제한된 정보 내에서 바로 학습하고 적용할 수 있는 방식을 의미합니다. 
      • 프롬프트 엔지니어링을 통해 이루어진다. 
      • 사용자가 프롬프트를 입력하면 gpt3는 텍스트를 분석해서 컨텍스트를 이해하고 관련출력을 생성하는것사용자가 오늘 기분이 슬퍼 라는 프롬프트를 입력하면 gpt3가 그것참 유감이군요 제가 도와드릴일이 있을까요 라는 출력을 생성하는걸 의미합니다. 
      • 한마디로 프롬프트의 내용만으로 하고자하는 task를 수행하는것을 말한다promt안의 맥락적의미(in context)를 이해하고 답변을 생성하는것프리트레이닝이나 파인튜닝같은 작업업이 별도의 학습과정이 존재하지않는다 
        • Zero shot 
          • Prompt: 빨간 사과가 영어로 뭐야? 
          • GPT: "Red Apple" 
        • One shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는? 
          • GPT: 노란 바나나는 "yellow 바나나"입니다. 
        • Few shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는 yellow 바나나야그럼 노란 사과는? 
          • GPT: 노란 사과는 "yellow 사과"입니다. 
      • 예시는 CoT, SC 임 
        • 전자는 단계별 사고로 분해해서 더 나은 추론을 만들어내는 전략 
        • 다양한 사고방식을 허용한다는 직관을 바탕으로함 

 

  • Retrieval-augmented generation(rag / 검색증강생성) 
    • Llm모델의 출력을 최적화 하여 응답을 생성하기 전에  데이터 소스 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 프로세스 
    • 이런 지식소스를 참조하여 다양한 환경에서 사용자 질문에 답변이 가능한 봇을 만드는것 
    • 1)검색모듈로 주어진 검색어나 질의에 따라 정보검색하고 문맥추출  
    • 2) 생성모듈로 앞서서 검색된정보들을 바탕으로 문장을 생성함 
  • ROLE-PLAY 
    •  예를 들어, Zhao 등 (2023a)은 프롬프트 "통계 분석 전문가로 가정해보세요."로 실험을 진행했다고함 

 

 

 

Preprocessing (테뷸러 데이터를 활용하여 데이터 직렬화 하는 방법) 

  • LIFT (Dinh et al., 2022)는 초기 노력 중 하나로, "열 이름은 값(Value)입니다"와 같은 자연어 문장 또는 "col1 = val1, col2 = val2, ..."와 같은 여러 방정식과 같은 직렬화 방법을 시도 
  • 동일한 결론은 TabLLM (Hegselmann et al., 2023)에서도 확인되었으며그들은 9가지 다른 직렬화 방법을 평가 
    • 텍스트로 구성된 모든 피처의 열거가 가장 우수한 성능을 발휘한다고 함(3번째 논문) 
  • TABLET논문방법을 사용하면 F1스코어가 매우 높게 오른다는걸 확인 
  • 스키마 기반의 프롬프트 엔지니어링 데이터셋의 배경 정보작업 설명요약 및 예시 데이터 포인트를 포함한다고 함 
  • Summary Boosting (Manikandan et al., 2023)은 데이터+메타데이터를 텍스트 프롬프트로 직렬화하여 요약을 생성 
  • Serilize-LM (Jaitly et al., 2023)는 도메인 특정 데이터셋에서 LLM 성능을 향상시키기 위해 3가지 혁신적인 직렬화 기술을 소개 
    • 차량 분류를 예로 들면제조사색상 및 차체 유형과 같은 속성이 이제 단일한 더 풍부한 문장으로 결합 
    • 또한, 가장 관련성이 높은 피처를 식별하기 위해 공분산을 활용하고, 해당 피처를 중요하다고 라벨링하거나 가장 중요한 피처를 설명하는 문장을 추가 (데이터의 경중을 판단한다는 뜻 같다) 
    • 마지막으로테이블 데이터를 LaTeX 코드 형식으로 변환 
  • UniPredict (Wang et al., 2023a)는 임의의 입력 M을 대상 설명과 피처의 의미론적 설명으로 통합하여 메타데이터를 형식화 
  • …. 

 

 

Time Series Forecasting (테이블 데이터 중에서도 시계열 예측 !!!!!!) 

  • ZeroTS (Gruver et al., 2023)은 GPT-3 (Brown et al., 2020)와 LLaMA-70B Touvron et al. (2023a)와 같은 LLM을 직접 시계열 예측에 사용 
    • 이 연구는 평균 절대 오차(MAE), 스케일 MAE 및 연속된 순위 확률 점수(CRPS)를 사용하여 모델을 평가하며LLM은 간단한 규칙 기반의 완성을 선호하고 반복 및 추세를 캡처하는 경향이 있다고 언급 
      • => llm은 시계열 예측에도 매우 효율적이다. 

 

  • Finetuning시 일반적으로현재 LLaMa가 가장 일반적으로 사용되는 모델이며, fine-tuning에는 soft prompt가 적합한 접근 방식이라고 함 
  • 메트릭으로는 MAE가 가장 일반적인 메트릭 

 

 

 

LLMs for tabular data generation (Tabular 데이터를 보완하는 새로운 방법론을 탐구-뉴데이터를 생성해서 활용) 

  • tabular데이터를 보완하는 새로운 방법론을 탐구 
  • Llm을 활용해서 새로운 tabular데이터를 생성하고 활용할 수 있는 방법들을 연구 
    • 한마디로 llm을 활용해서 데이터를 생성해서 활용한다 

 

  • Borisov et al. (2023b)은 원본 tabular 데이터의 특성을 가진 합성 샘플을 생성하기 위해 GReaT11 (Generation of Realistic Tabular data) 제안. GReaT 데이터 파이프라인은 문장 직렬화 방법을 사용하여 tabular 데이터를 의미 있는 텍스트로 변환하는 텍스트 인코딩 단계와 관련. 이후에는 GPT-2 또는 GPT-2 distill 모델을 미세 조정하는 과정이 이어짐.  
  • REaLTabFormer (Solatorio & Dupriez, 2023)은 GReaT를 확장하여 비관계형 및 관계형 타블러 데이터를 생성 
  • 등등.... 

++ figure4  참조

  • 이러한 합성 데이터의 평가방법 4가지 
    1. 저차원 통계열별 밀도와 열 간의 상관관계를 평가하여 개별 열의 분포와 열 간의 관계를 파악 (열별 데이터분포를 살펴봄으로써 다양성과 일관성을 평가한다예를들면 열값이 균일하게 분포되어있는지확인가능. 또 상관관계를 통해서 음의 상관관계이니지 직선적인 상관관계인지 등등 파악가능) 
    2. 고차원 측정합성 데이터의 전체적인 신뢰성과 다양성을 측정하는 지표를 사용합니다. (=다양한 관점에서데이터품질과 다양성을 측정예를들어 실제데이터와 얼마나 유사한가 같은 지표) 
    3. 개인 정보 보호원본 데이터의 개인 정보 보호 수준을 평가하기 위해 최근접 레코드와의 거리를 계산하는 지표를 사용합니다.(개인식별 가능성을 평가함원본데이터랑 유사도를 평가해서 유사할수록 개인정보 식별 가능서이 높아지고유사도가 낮을수록 개인정보수준이 높아진다)) 
    4. 하위 작업 성능합성 데이터를 사용하여 학습한 모델이 실제 데이터에서 얼마나 잘 작동하는지 평가합니다. 

 

 

 

LLMs for table understanding 

  • TABLE QA  
  • Table and Conversation QA = QA인데 테이블만 사용하는게 아니라 다른 형식의 정보들도 같이 사용하여 대화를 진행 
  • Table Classification = 테이블을 종류별로 분류하는것 
  • Text2SQL = sql 생성 
  • Table NLG = 원본 테이블에 대한 설명을 생성 
  • Table NLI = 테이블안의 관계에 대해 분석(2019에 많이 팔린 상품은 무엇) 
  • Domain Specific = 영역별로 특화항공업계는  AIT-QA (Katsis et al., 2022)를 사용하는 것을 권장금융 관련 테이블 질문 답변 작업에는 TAT-QA (Zhu et al., 2021a)를 사용하는 것을 추천대략적으로 업계별로 추천하는것이 다르다는것으로 이해 
  • Pretraining = 테이블+영어문맥설명으로 프리트레이닝하면 테이블 이해해 더 좋은 결과를 볼수 있다라고 함 

 

 

General ability of LLMs in QA 

 

  • Numerical QA = 수학 추론을 필요로 하는 질문(American Express의 평균 거래 별 결제량은 얼마입니까?) 
  • Text2SQL =  Liu et al. (2023c)은 세 가지 유형의 키워드를 식별하는 질문 매처를 설계: 1) 열 이름과 관련된 용어, 2) 제한과 관련된 구절(예: "상위 10개"), 3) 알고리즘 또는 모듈 키워드. 
  • Impact of model size on performance=WebTableQuestions에서 6.7B 대 175B GPT-3 모델을 비교할 때, 작은 모델은 더 큰 모델의 점수의 절반만 달성 
  • Finetuning or No finetuningLLMs(>70B 파라미터)를 파인튜닝하는 것에는 매우 제한적인 연구가 진행 

 

 

QA 관련 논문들 

  • Chain-of-command (CoC)-사용자입력을 중간명령작업의 순서열로 변환
  • Deng et al. (2022b)는 QA 작업을 세 가지 하위 작업으로 분할 
    • 불확실성을 명확히 하기 위해 질문을 할 것인지를 결정하는 Clarification Need Prediction (CNP)
    • 명확히 하기 위해 질문을 생성하는 Clarification Question Generation (CQG)
    • 질문에 대한 명확히가 필요하지 않은 경우 바로 답변을 생성하는 Conversational Question Answering (CQA)
  • 검색능력도 중요함. 검색능력은 아래와같이 두가지 유형으로 나뉨
    • 질문과 관련된 정보를 찾기 ( 예를들어 무슨열의 무슨행의 값을 구해줘(
    • 추가정보와 예제를 얻는것
  • 데이터 메인테이블 관련
    • Zhao et al. (2023d)는 최상위-n개의 가장 관련성이 높은 문서를 반환하는 검색 모듈 (retriever module)의 성능 향상이 수치적 QA에서 최종 정확도를 일관되게 향상시킨다는 것을 관찰
    • . Sui et al. (2023c)는 여러 개의 테이블 샘플링 방법 (행과 열)과 토큰 제한 매개변수를 기반으로 한 테이블 패킹을 탐구(질문과 가장 의미적으로 유사한 행을 검색)
    •  Dong et al. (2023)는 SC(Self-consistency, 또다른논문이다)를 사용하여 질문과 관련성에 따라 테이블을 순위 매김하기 위해 ChatGPT를 사용. 그 결과 10개세트의 검색결과를 생성한다음, 가장 자주보이는 세트를 선택. 이때도 SC방법이 사용되었다고함. 
    •  cTBLS Sundar & Heck (2023)는 검색된 테이블 정보에 기반한 대화 응답을 검색하고 생성하기 위한 세 단계 아키텍처를 설계함
      • RoBERTa (Liu et al., 2019)에서 유도된 양방향 인코더 기반의 Dense Table Retrieval (DTR) 모델을 사용해서 연관성이 가장높은 테이블을 식별(인코더만 사용한다)
      • 두 번째 단계에서 트리플릿 손실을 사용하여 행을 순위 매기기 위한 Coarse System State Tracking 시스템을 사용 (??)
      • 마지막으로, GPT-3.5는 그룹화된 지식 원본을 기준으로 한 쿼리와 관련성이 가장 높은 셀을 조건으로 하는 추가 질문에 대한 자연어 응답을 생성
      • INPUT = 질의 기록, 순위 매김된 지식 원본 및 답변해야 할 질문이 포함된 프롬프트가 입력으로 제공
    • . Zhao et al. (2023d)은 OpenAI의 Ada Embedding4과 Contriever (Izacard et al., 2022)를 검색기로 사용하고 BM25 (Robertson et al., 1995)를 희소 검색기로 사용. 여기서 말하는 검색기란 가장 관련성이 높은 텍스트랑 테이블을 추출하는데 도움을 주는것. 이 추출된 정보는 질문에 대한 입력 컨텍스트로 제공됩니다.
  • 예제선별관련
    • Gao et al. (2023)는 1) 무작위로 K개 선택 2) 질문의 유사성을 선택(유사성기준은 유클리드거리같은 사전에 정의된 기준을 사용) 3) 마스킹된 질문 유사성을 선택한다.(=질문과 예제간의 유사성을 평가해서 예제를 선택하는것) 4) 대상 SQL 쿼리 s∗와 유사한 k개의 예제를 선택.

 

Multi-turn tasks

LLM을 반복적으로 호출하는 파이프라인을 설계

3가지 카테고리로 분류된다

(1) 어려운 작업을 처리 가능한 하위 작업으로 분해하기 위해 (너무 복잡한 요청을 작은 여러개 작업으로 나눔)

  • Suiet al. (2023b)은 하류 테이블 추론을 개선하기 위해 두 단계의 self-augmented prompting approach를 제안. 첫 번째로 프롬프트를 사용하여 LLM에게 테이블에 대한 중간 출력을 생성하도록 요청한 다음, 응답을 두 번째 프롬프트로 통합하여 하류 작업의 최종 답변을 요청한다.
  • Ye et al.(2023b)은 또한 대량의 테이블을 작은 테이블로 분해하고 복잡한 질문을 텍스트 추론을 위해 단순한 하위 질문들로 변환하도록 LLM에게 안내
  •  Liu 등(2023e)의 경우, 상징적인 CoT 추론 경로를 촉진하기 위해, 모델이 명령을 실행하고 데이터를 처리하며 결과를 검토할 수 있는 Python 셸과 상호작용하도록 허용  

(2) 새로운 사용자 입력에 기반하여 모델 출력을 업데이트하기 위해

  •  SParC의 경우, Spider (Yu 등, 2018b)를 기반으로 연이어 따르는 질문을 설계

(3) 특정 제약 조건을 해결하거나 오류를 수정하기 위해

  • Zhao 등(2023a)은 테이블이 API 입력 제한을 초과하는 경우 다중 턴 프롬프트를 사용하여 이를 해결. 잘못된 부분이 생성되었을 경우 잘못된 경우를 LLM을 되돌려주는 반복적인 과정이 도움이 될수 있다고함.

 

 

아웃풋 평가 방식

  • F1이 일반적이긴함
  • ROUGE
  • BLEU
  • 시각화..

 

 

한계점과 미래방안

  • Bias and fairness llm의 내재적인 편향 완화
  • Hallucination 실제가 아닌값을 생성할 위험 (의료계쪽에서는 치명적)
  • Numerical representation 숫자는 임베딩이 꼭 필요
  • Categorical representation 컨텍스트 제한 초과시 데이터 일부가 날라가서 성능에 부정적이어짐. 이를 커버할수있는 인코딩방식이 필요
  • Standard benchmark 너무 다양하기 때문에 표준화된 벤치마크의 필요성
  • Model interpretability 데이터 이해능력의 탐구
  • Easy to use 대부분 데이터 직렬화가 필요해서 모델 엑세스가 쉽지않음. 다른사람들이 사용하기 쉬워야함.(자동전처리나 직렬화를 통합시킨다면 훨씬 쉬울것)
  • Fine-tuning strategy design llm모델의 적합한 모델과 학습전략
  • Model grafting 특화된 인코더를 사용해서 비문자 데이터를 매핑..한마디로 텍스트가 아닌 다른 유형의 데이터를 모델이 자체적으로 인코딩할수있다..

[중요내용 정리]

 

TABULAR  특징 

  1. 데이터의 다양성 ( 이진,수치형,텍스트같은 다양한 유형포함) 
  2. 불균형한 레이블과 없는값들이 많을수도 
  3. 전처리 필요성 
  4. 컨텍스트기반의 상호연결(예를들어 나이,교육수준,음주는 연결된) 
  5. 순서 무관 
  6. 사전지식의 부재 - 종종 이미지나 오디오데이터는 사전지식이 필요하다 

 

전통적인 tabular data과 딥러닝 활용 

  • Gradient Boosted Decision Trees 
  • 부스팅앙상블 
    • 한계점1 : 범주형특징같은것에 민감할수있으며암묵적 학습 수행이 가능 
    • 한계점2 : 시계열 데이터의 경우 처리하기 적합하지않다 
    • 한계점3 : 전체 분포가 골고루지 않을경우 일반화하기 어려울수 있다 
  • CNN방법론은 여러가지로 발전 
    • 데이터변환 
    • 미분가능트리 
    • 어텐션기반(TABNET) 
    • 정규화 
  • 여러가지 시도가 있었음에도 XGBoostLightGBMCatBoost 등을 포함한 GBDT 알고리즘 들이 여전히 우수함 
    • 베이지안 네트워크같은 딥러닝 적급낭버보가 LLM같은 생성모델의 발전 
  • LLM의 가장 전통적인 건 QA 
    • QA : TAPAS (Herzig et al., 2020), TABERT (Yin et al., 2020b), TURL (Deng et al., 2022a), TUTA (Wang et al., 2021), TABBIE (Iida et al., 2021) 

 

LLM의 간단설명(여기선 대형 PLM이라고도 부름) 

  • 모델은 텍스트 말뭉치의 일반적인 문법 및 의미적 이해를 얻은 후, 과제별 목적에 맞추어 훈련됩니다 
  • 이전 연구에서는 표형식 데이터의 표현 학습을 위해 LM을 사용하였으나 이는 제한적이었습니다향후 연구에서는 표 데이터를 텍스트로 변환하여 PLM을 활용하여 의미 정보와 헤더 정보를 고려한 문맥적 표현을 학습하는 방법을 제안하였습니다이를 통해 크로스 테이블 학습과 특성 열의 순열 불변성을 지니는 모델을 구축하는 것이 가능해졌습니다. 

 

현재 LLM의 잠재력에 대해 계속 탐구하고 있음. 

  1. 딥 러닝 방법은 초기 훈련에서 사용되지 않은 데이터셋에서는 최적의 성능을 보이지 않는 경우가 많기 때문에사전 훈련과 세밀 조정 패러다임을 활용한 전이 학습이 매우 유망합니다. (= 파인튜닝) 
  2. 표 데이터를 LLM에서 읽을 수 있는 자연 언어로 변환함으로써고차원 범주형 데이터의 one-hot 인코딩에 따른 차원의 저주(curse of dimensionality)를 피할 수 있습니다. (테뷸러 데이터를 txt로 변환해서 고차원문제를 해결) 
  3. CoT를 통한 단계적인 추론과 같은 신생 능력은 LM을 언어 모델링에서 보다 일반적인 작업 해결 도구로 변형시켰습니다LLM의 신생 능력이 표 데이터 모델링에서 얼마나 작동하는지 테스트하기 위해 더 많은 연구가 필요합니다.(cot 단계적 구성성단계적 추론은 다양한 작업에 적용할수있게 해준다) 

 

Contribtion 

  1. LLM을 타블로 데이터 예측타블로 데이터 합성타블로 데이터 질문 답변테이블 이해와 같은 분야들을 세분화하여 분류 
  2. 타블로 데이터에 LLM을 적용한 방법을 평가하는 다양한 측정 항목에 대한 현황과 분류법을 조사 (한마디로 정확도 측정 방법을 조사) 
  3. 많이들 사용되는데이터셋에 대한 현황과 분류법을 조사 
  4. Table data + llm 의 현황과 분류법 
  5. 도전과제와 개요 

 

Key techniques for LLMs’ applications on tabular data 

  • 직렬화 
    • Tabular -> text (text/json/xml...) 
      • 표를 쉼표같은 구분기호로 변환도 가능 
      • 마크다운 형식으로 변환도 가능 
  • Embedding based (직렬화 한걸 벡터화) 
    • Bert를 기반으로 하는 다양한 테이블 인코더들이 있다. 
  • 그래프기반,트리기반 데이터구조로 변환 
    • 하지만 직렬화를 해줘야 한다고  
  • 데이터 형식이 정확도에 매우 민감 
    • 예를 들어DFLoader와 JSON 형식이 테이블 변환 작업에 더 적합하다는 연구 결과와 HTML 또는 XML 테이블 형식이 GPT 모델에서 더 잘 이해되는 것을 보여주는 연구 결과가 있습니다 
  • 추가정보 
    • 직렬화+임베딩을 한번에 하는 방법들도 있다고함 (표에대한설명을 문장으로생성) 
      • LMs (Fine-tuned BLOOM on ToTTo (Parikh et al., 2020b), T0++ (Sanh et al., 2022), GPT-3 (Ouyang et al., 2022)) 
    • Few-shot분류시 전통적인 리스트와 텍스트 템플릿이 llm 직렬화보다 성능이 더 좋았다고함 
    • 복잡하고 큰 LLM일수록 성능이좋다 

 

Table 조작(고려해야할 사항) 

  • LLM모델은 인풋시 텍스트 제한이 있다. 2048토큰까지 처리가능. Llama2는 4048토큰지원. 만약 테이블이 너무 크면부족할수가있다 
  • 길이는 문제 없어도 긴문장을 처리시에 비효율적이다. ' 
    • 1000토큰이상일경우 GPT3에서 성능저하를 확인 
  • 긴 프롬프트는 LLM 기반에서 너무 비싸다 

 

Prompt engineering 

  • 프롬프트 = llm에 입력되는 텍스트 
    • 가장간단한 형식은 문자열 
    • IN-CONTEXT LEARNING = 유사한예를 통합하여 LLM이 원하는 결과를 이해하는데 도움이 되는걸 의미 
      • In-Context Learning은 특정한 맥락(context) 내에서 필요한 정보를 바탕으로 학습하는 방식을 말합니다이는 기존의 대규모 데이터 세트를 통해 사전 학습(pre-training)하는 과정 없이제한된 정보 내에서 바로 학습하고 적용할 수 있는 방식을 의미합니다. 
      • 프롬프트 엔지니어링을 통해 이루어진다. 
      • 사용자가 프롬프트를 입력하면 gpt3는 텍스트를 분석해서 컨텍스트를 이해하고 관련출력을 생성하는것사용자가 오늘 기분이 슬퍼 라는 프롬프트를 입력하면 gpt3가 그것참 유감이군요 제가 도와드릴일이 있을까요 라는 출력을 생성하는걸 의미합니다. 
      • 한마디로 프롬프트의 내용만으로 하고자하는 task를 수행하는것을 말한다promt안의 맥락적의미(in context)를 이해하고 답변을 생성하는것프리트레이닝이나 파인튜닝같은 작업업이 별도의 학습과정이 존재하지않는다 
        • Zero shot 
          • Prompt: 빨간 사과가 영어로 뭐야? 
          • GPT: "Red Apple" 
        • One shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는? 
          • GPT: 노란 바나나는 "yellow 바나나"입니다. 
        • Few shot 
          • Prompt: 빨간 사과는 red 사과라고 할께노란 바나나는 yellow 바나나야그럼 노란 사과는? 
          • GPT: 노란 사과는 "yellow 사과"입니다. 
      • 예시는 CoT, SC 임 
        • 전자는 단계별 사고로 분해해서 더 나은 추론을 만들어내는 전략 
        • 다양한 사고방식을 허용한다는 직관을 바탕으로함 

 

  • Retrieval-augmented generation(rag / 검색증강생성) 
    • Llm모델의 출력을 최적화 하여 응답을 생성하기 전에  데이터 소스 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 프로세스 
    • 이런 지식소스를 참조하여 다양한 환경에서 사용자 질문에 답변이 가능한 봇을 만드는것 
    • 1)검색모듈로 주어진 검색어나 질의에 따라 정보검색하고 문맥추출  
    • 2) 생성모듈로 앞서서 검색된정보들을 바탕으로 문장을 생성함 
  • ROLE-PLAY 
    •  예를 들어, Zhao 등 (2023a)은 프롬프트 "통계 분석 전문가로 가정해보세요."로 실험을 진행했다고함 

 

 

 

Preprocessing (테뷸러 데이터를 활용하여 데이터 직렬화 하는 방법) 

  • LIFT (Dinh et al., 2022)는 초기 노력 중 하나로, "열 이름은 값(Value)입니다"와 같은 자연어 문장 또는 "col1 = val1, col2 = val2, ..."와 같은 여러 방정식과 같은 직렬화 방법을 시도 
  • 동일한 결론은 TabLLM (Hegselmann et al., 2023)에서도 확인되었으며그들은 9가지 다른 직렬화 방법을 평가 
    • 텍스트로 구성된 모든 피처의 열거가 가장 우수한 성능을 발휘한다고 함(3번째 논문) 
  • TABLET논문방법을 사용하면 F1스코어가 매우 높게 오른다는걸 확인 
  • 스키마 기반의 프롬프트 엔지니어링 데이터셋의 배경 정보작업 설명요약 및 예시 데이터 포인트를 포함한다고 함 
  • Summary Boosting (Manikandan et al., 2023)은 데이터+메타데이터를 텍스트 프롬프트로 직렬화하여 요약을 생성 
  • Serilize-LM (Jaitly et al., 2023)는 도메인 특정 데이터셋에서 LLM 성능을 향상시키기 위해 3가지 혁신적인 직렬화 기술을 소개 
    • 차량 분류를 예로 들면제조사색상 및 차체 유형과 같은 속성이 이제 단일한 더 풍부한 문장으로 결합 
    • 또한, 가장 관련성이 높은 피처를 식별하기 위해 공분산을 활용하고, 해당 피처를 중요하다고 라벨링하거나 가장 중요한 피처를 설명하는 문장을 추가 (데이터의 경중을 판단한다는 뜻 같다) 
    • 마지막으로테이블 데이터를 LaTeX 코드 형식으로 변환 
  • UniPredict (Wang et al., 2023a)는 임의의 입력 M을 대상 설명과 피처의 의미론적 설명으로 통합하여 메타데이터를 형식화 
  • …. 

 

 

Time Series Forecasting (테이블 데이터 중에서도 시계열 예측 !!!!!!) 

  • ZeroTS (Gruver et al., 2023)은 GPT-3 (Brown et al., 2020)와 LLaMA-70B Touvron et al. (2023a)와 같은 LLM을 직접 시계열 예측에 사용 
    • 이 연구는 평균 절대 오차(MAE), 스케일 MAE 및 연속된 순위 확률 점수(CRPS)를 사용하여 모델을 평가하며LLM은 간단한 규칙 기반의 완성을 선호하고 반복 및 추세를 캡처하는 경향이 있다고 언급 
      • => llm은 시계열 예측에도 매우 효율적이다. 

 

  • Finetuning시 일반적으로현재 LLaMa가 가장 일반적으로 사용되는 모델이며, fine-tuning에는 soft prompt가 적합한 접근 방식이라고 함 
  • 메트릭으로는 MAE가 가장 일반적인 메트릭 

 

 

 

LLMs for tabular data generation (Tabular 데이터를 보완하는 새로운 방법론을 탐구-뉴데이터를 생성해서 활용) 

  • tabular데이터를 보완하는 새로운 방법론을 탐구 
  • Llm을 활용해서 새로운 tabular데이터를 생성하고 활용할 수 있는 방법들을 연구 
    • 한마디로 llm을 활용해서 데이터를 생성해서 활용한다 

 

  • Borisov et al. (2023b)은 원본 tabular 데이터의 특성을 가진 합성 샘플을 생성하기 위해 GReaT11 (Generation of Realistic Tabular data) 제안. GReaT 데이터 파이프라인은 문장 직렬화 방법을 사용하여 tabular 데이터를 의미 있는 텍스트로 변환하는 텍스트 인코딩 단계와 관련. 이후에는 GPT-2 또는 GPT-2 distill 모델을 미세 조정하는 과정이 이어짐.  
  • REaLTabFormer (Solatorio & Dupriez, 2023)은 GReaT를 확장하여 비관계형 및 관계형 타블러 데이터를 생성 
  • 등등.... 

++ figure4  참조

  • 이러한 합성 데이터의 평가방법 4가지 
    1. 저차원 통계열별 밀도와 열 간의 상관관계를 평가하여 개별 열의 분포와 열 간의 관계를 파악 (열별 데이터분포를 살펴봄으로써 다양성과 일관성을 평가한다예를들면 열값이 균일하게 분포되어있는지확인가능. 또 상관관계를 통해서 음의 상관관계이니지 직선적인 상관관계인지 등등 파악가능) 
    2. 고차원 측정합성 데이터의 전체적인 신뢰성과 다양성을 측정하는 지표를 사용합니다. (=다양한 관점에서데이터품질과 다양성을 측정예를들어 실제데이터와 얼마나 유사한가 같은 지표) 
    3. 개인 정보 보호원본 데이터의 개인 정보 보호 수준을 평가하기 위해 최근접 레코드와의 거리를 계산하는 지표를 사용합니다.(개인식별 가능성을 평가함원본데이터랑 유사도를 평가해서 유사할수록 개인정보 식별 가능서이 높아지고유사도가 낮을수록 개인정보수준이 높아진다)) 
    4. 하위 작업 성능합성 데이터를 사용하여 학습한 모델이 실제 데이터에서 얼마나 잘 작동하는지 평가합니다. 

 

 

 

LLMs for table understanding 

  • TABLE QA  
  • Table and Conversation QA = QA인데 테이블만 사용하는게 아니라 다른 형식의 정보들도 같이 사용하여 대화를 진행 
  • Table Classification = 테이블을 종류별로 분류하는것 
  • Text2SQL = sql 생성 
  • Table NLG = 원본 테이블에 대한 설명을 생성 
  • Table NLI = 테이블안의 관계에 대해 분석(2019에 많이 팔린 상품은 무엇) 
  • Domain Specific = 영역별로 특화항공업계는  AIT-QA (Katsis et al., 2022)를 사용하는 것을 권장금융 관련 테이블 질문 답변 작업에는 TAT-QA (Zhu et al., 2021a)를 사용하는 것을 추천대략적으로 업계별로 추천하는것이 다르다는것으로 이해 
  • Pretraining = 테이블+영어문맥설명으로 프리트레이닝하면 테이블 이해해 더 좋은 결과를 볼수 있다라고 함 

 

 

General ability of LLMs in QA 

 

  • Numerical QA = 수학 추론을 필요로 하는 질문(American Express의 평균 거래 별 결제량은 얼마입니까?) 
  • Text2SQL =  Liu et al. (2023c)은 세 가지 유형의 키워드를 식별하는 질문 매처를 설계: 1) 열 이름과 관련된 용어, 2) 제한과 관련된 구절(예: "상위 10개"), 3) 알고리즘 또는 모듈 키워드. 
  • Impact of model size on performance=WebTableQuestions에서 6.7B 대 175B GPT-3 모델을 비교할 때, 작은 모델은 더 큰 모델의 점수의 절반만 달성 
  • Finetuning or No finetuningLLMs(>70B 파라미터)를 파인튜닝하는 것에는 매우 제한적인 연구가 진행 

 

 

QA 관련 논문들 

  • Chain-of-command (CoC)-사용자입력을 중간명령작업의 순서열로 변환
  • Deng et al. (2022b)는 QA 작업을 세 가지 하위 작업으로 분할 
    • 불확실성을 명확히 하기 위해 질문을 할 것인지를 결정하는 Clarification Need Prediction (CNP)
    • 명확히 하기 위해 질문을 생성하는 Clarification Question Generation (CQG)
    • 질문에 대한 명확히가 필요하지 않은 경우 바로 답변을 생성하는 Conversational Question Answering (CQA)
  • 검색능력도 중요함. 검색능력은 아래와같이 두가지 유형으로 나뉨
    • 질문과 관련된 정보를 찾기 ( 예를들어 무슨열의 무슨행의 값을 구해줘(
    • 추가정보와 예제를 얻는것
  • 데이터 메인테이블 관련
    • Zhao et al. (2023d)는 최상위-n개의 가장 관련성이 높은 문서를 반환하는 검색 모듈 (retriever module)의 성능 향상이 수치적 QA에서 최종 정확도를 일관되게 향상시킨다는 것을 관찰
    • . Sui et al. (2023c)는 여러 개의 테이블 샘플링 방법 (행과 열)과 토큰 제한 매개변수를 기반으로 한 테이블 패킹을 탐구(질문과 가장 의미적으로 유사한 행을 검색)
    •  Dong et al. (2023)는 SC(Self-consistency, 또다른논문이다)를 사용하여 질문과 관련성에 따라 테이블을 순위 매김하기 위해 ChatGPT를 사용. 그 결과 10개세트의 검색결과를 생성한다음, 가장 자주보이는 세트를 선택. 이때도 SC방법이 사용되었다고함. 
    •  cTBLS Sundar & Heck (2023)는 검색된 테이블 정보에 기반한 대화 응답을 검색하고 생성하기 위한 세 단계 아키텍처를 설계함
      • RoBERTa (Liu et al., 2019)에서 유도된 양방향 인코더 기반의 Dense Table Retrieval (DTR) 모델을 사용해서 연관성이 가장높은 테이블을 식별(인코더만 사용한다)
      • 두 번째 단계에서 트리플릿 손실을 사용하여 행을 순위 매기기 위한 Coarse System State Tracking 시스템을 사용 (??)
      • 마지막으로, GPT-3.5는 그룹화된 지식 원본을 기준으로 한 쿼리와 관련성이 가장 높은 셀을 조건으로 하는 추가 질문에 대한 자연어 응답을 생성
      • INPUT = 질의 기록, 순위 매김된 지식 원본 및 답변해야 할 질문이 포함된 프롬프트가 입력으로 제공
    • . Zhao et al. (2023d)은 OpenAI의 Ada Embedding4과 Contriever (Izacard et al., 2022)를 검색기로 사용하고 BM25 (Robertson et al., 1995)를 희소 검색기로 사용. 여기서 말하는 검색기란 가장 관련성이 높은 텍스트랑 테이블을 추출하는데 도움을 주는것. 이 추출된 정보는 질문에 대한 입력 컨텍스트로 제공됩니다.
  • 예제선별관련
    • Gao et al. (2023)는 1) 무작위로 K개 선택 2) 질문의 유사성을 선택(유사성기준은 유클리드거리같은 사전에 정의된 기준을 사용) 3) 마스킹된 질문 유사성을 선택한다.(=질문과 예제간의 유사성을 평가해서 예제를 선택하는것) 4) 대상 SQL 쿼리 s∗와 유사한 k개의 예제를 선택.

 

Multi-turn tasks

LLM을 반복적으로 호출하는 파이프라인을 설계

3가지 카테고리로 분류된다

(1) 어려운 작업을 처리 가능한 하위 작업으로 분해하기 위해 (너무 복잡한 요청을 작은 여러개 작업으로 나눔)

  • Suiet al. (2023b)은 하류 테이블 추론을 개선하기 위해 두 단계의 self-augmented prompting approach를 제안. 첫 번째로 프롬프트를 사용하여 LLM에게 테이블에 대한 중간 출력을 생성하도록 요청한 다음, 응답을 두 번째 프롬프트로 통합하여 하류 작업의 최종 답변을 요청한다.
  • Ye et al.(2023b)은 또한 대량의 테이블을 작은 테이블로 분해하고 복잡한 질문을 텍스트 추론을 위해 단순한 하위 질문들로 변환하도록 LLM에게 안내
  •  Liu 등(2023e)의 경우, 상징적인 CoT 추론 경로를 촉진하기 위해, 모델이 명령을 실행하고 데이터를 처리하며 결과를 검토할 수 있는 Python 셸과 상호작용하도록 허용  

(2) 새로운 사용자 입력에 기반하여 모델 출력을 업데이트하기 위해

  •  SParC의 경우, Spider (Yu 등, 2018b)를 기반으로 연이어 따르는 질문을 설계

(3) 특정 제약 조건을 해결하거나 오류를 수정하기 위해

  • Zhao 등(2023a)은 테이블이 API 입력 제한을 초과하는 경우 다중 턴 프롬프트를 사용하여 이를 해결. 잘못된 부분이 생성되었을 경우 잘못된 경우를 LLM을 되돌려주는 반복적인 과정이 도움이 될수 있다고함.

 

 

아웃풋 평가 방식

  • F1이 일반적이긴함
  • ROUGE
  • BLEU
  • 시각화..

 

 

한계점과 미래방안

  • Bias and fairness llm의 내재적인 편향 완화
  • Hallucination 실제가 아닌값을 생성할 위험 (의료계쪽에서는 치명적)
  • Numerical representation 숫자는 임베딩이 꼭 필요
  • Categorical representation 컨텍스트 제한 초과시 데이터 일부가 날라가서 성능에 부정적이어짐. 이를 커버할수있는 인코딩방식이 필요
  • Standard benchmark 너무 다양하기 때문에 표준화된 벤치마크의 필요성
  • Model interpretability 데이터 이해능력의 탐구
  • Easy to use 대부분 데이터 직렬화가 필요해서 모델 엑세스가 쉽지않음. 다른사람들이 사용하기 쉬워야함.(자동전처리나 직렬화를 통합시킨다면 훨씬 쉬울것)
  • Fine-tuning strategy design llm모델의 적합한 모델과 학습전략
  • Model grafting 특화된 인코더를 사용해서 비문자 데이터를 매핑..한마디로 텍스트가 아닌 다른 유형의 데이터를 모델이 자체적으로 인코딩할수있다

 

2. Large Language Model for Table Processing: A Survey

Large Language Model for Table Processing_ A Survey의 사본 (1).pptx
5.03MB

 

3.TabLLM: Few-shot Classification of Tabular Data with Large Language Models 

4. Large Language Models Can Automatically Engineer Features for Few-Shot Tabular Learning

  • transformer 구조을 알기 위해서는 attention is all you need라는 논문을 보면된다.
  • transformer 구조는 아래그림과 같다.

 

  • 여기서 정리할것들
    • self attention
    • multi head attention
    • feed forward
    • add & Norm

 

1. Self Attention

 

참조 (아래 더보기 클릭)

  • 위의 구조가 self-attention의 핵심구조이다.
  • (MASK 모듈은 생성형 AI에 주로 쓰이니 생략해도 된다고 함)

 

<self attention 설명>

  • embedding_dimension이 d_model
  • I love you가 입력 x 이고  가로는 d_m or d_model이라고 부를거고 세로는 T개라고 명명하겠음
  • wq,wk,wv는 파라미터
  • Q,K,V는 X(입력벡터시퀀스)에 WQ,Wk,WV를 곱해서 구해준다.
  • WQ,Wk,WV는 Task(예: 기계 번역)를 가장 잘 수행하는 방향으로 학습 과정에서 업데이트됨
  • QK^T를 곱한 이유는 각 단어와 단어간의 상관관계를 보기위해서
    • Q의 (0,0) K의 (0,0)를 곱한숫자는 I와 I간의 상관관계가 어느정도인지 나타낸것과 같다고 볼 수 있다.
    • dk^1/2를 나눠주는 이유는 숫자가 극단적으로 갈수있는것을 예방하여 smoothing 한것과 동일하게 이해하면 된다
  • softmax를 적용한이유는 0-1사이의 숫자로 나타내주기위함
  • softmax(QK^T)를 해준다음 V를 곱한것의 의미는
    • I love you라는 문장에 각 i,love,you와의 상관관계를 적용해준것과 같다.
    • 예를들어서 배를 먹었더니 배가 아프다 라는 문장에서 먹는배와 , 신체 배의 차이를 극대화하는 과정과 같다. 먹었다,아프다 라는단어와의 상관관계를 분석하여 배라는 단어가 어떤것에 더 가까운지 확실히하는 과정이라고 생각하면 된다.
  • 위사진에서 4, embedding dimension이 의미하는것은?
    • 자연어처리에서는 단어가 들어오면 단어를 토큰화하고, word embedding을 통해서 벡터화한다.
      • 어떤흐름으로 진행되는지는 아래 그림을 참조
      • integer부분이 토큰화, lookup table에서 한줄 뽑아온것(위그림의 단어별로 존재하는 리스트) 바로 임베딩 벡터를 의미한다.

⇒ 한마디로 이과정은 각각의 단어들을 비교해서 문맥을 파악하고, 벡터표현값을 업데이트하는 과정

 

< 헷갈리는것들 >

여기서 간과하면 안되는점 : Wq의 크기는 d_model x d_model이다. (Tx d_model) x (d_model*d_model) 이렇게 행렬곱셈을 하면 결과값 크기도 input과 동일한 T x d_model이 나옴

 

<추가설명>

  • 위사진에서 4, embedding dimension이 의미하는것은?
    • 자연어처리에서는 단어가 들어오면 단어를 토큰화하고, word embedding을 통해서 벡터화한다.
      • 어떤흐름으로 진행되는지는 아래 그림을 참조하자
      • 아래그림에서 integer부분이 토큰화, lookup table에서 한줄 뽑아온것(위그림의 단어별로 존재하는 리스트) 바로 임베딩 벡터를 의미한다.

 

 

2. Multihead attention

 

참조 (아래 더보기 클릭)

위 그림이 논문에 나온 그림이다.

 

  • h는 사용자가 직접 정해준다. 멀티헤드를 몇개로 지정해줄것인가를 뜻한다.
  • h(멀티헤드 갯수)를 직접 정해주지않으면 디폴트값은 12개이다.
  • 앞에서 self attention으로 구한 블럭을 가로로 나란히 h개 붙인다
  • 그다음, w0 행렬에 곱해서 linear하게 재정렬한다.
  • 한마디로 맨위에서 wo랑 곱하는 과정이 concat
  • concat를 해서 리니어하게 재정렬 된다는것을 의미한다.
  • transformer paper에서 w0는 가로세로 길이가 같음 (d0=dv*h)

 

 

참조 : https://medium.com/analytics-vidhya/understanding-bert-architecture-3f35a264b187

위 링크에서 보면 keras_bert로 multihead attention이 끝나고 파라미터수가 Bert는 인코더수가 12개이기 때문에 encoder-1의 multihead self attnetion의 파라미터수가 2,362,368개가 나오는지 계산해보자

import keras
from keras_bert import get_base_dict, get_model, compile_model, gen_batch_inputs

model = get_model(
    token_num=30000,
    head_num=12,
    transformer_num=12,
    embed_dim=768,
    feed_forward_dim=3072,
    seq_len=500,
    pos_num=512,
    dropout_rate=0.05
)
model.summary()

  • parameter를 구하기위해서는 위에서 wq,wk,wv랑 w0의 수를 모두 더해주면된다.
  • 일반적으로 self-attention에서는 w1q크기가 d_model x d_model이지만 여기서는 multihead attention이기 떄문에 d_model x d_model/h 로 구성되게 된다.
    • 위의 예제에서 dm = 768, h=12로 지정해준 상태이다.
    • 그렇다면 wq의 크기는 768*64 근데 이게 k,v,q 이렇게 3개가 있으니까 3을 곱해주고, 헤드가 12개니까 12도 곱해준다.
    • 그런데 바이어스도 더해줘야한다고함..
    • 그렇다면 wq,wv,wk의 모든 파라미터갯수는 76864312+7683
    • w0은 쉽다. d_model x d_model인데 여기도 바이어스값을 더해줘야한다고
      • 그래서 768*768 + 768
    • 모두다 더해주면 2362368개의 파라미터수가 나온다!

 

 

3. Layer Norm

 

  • 그림에서는 norm이 multihead 다음, 피드 포워드 다음에 진행되지만 최근 LLM모델들은 전부 norm을 먼저 진행한다고 한다 (최근은 순서가 반대라고함)
    • 실제로 아래 BERT모델을 보면 Layer norm을 먼저하고나서 multihead attention을 진행한다.

  • 먼저 딥러닝을 진행할때 activation function에서 input데이터들이 너무 왼쪽이나 너무 오른쪽에 붙으면 문제가 생김
  • 그걸 방지하고자 nomarlization을 진행, 이때 정규화분포의 모양과 위치는 감마와 베타가 결정함.

  • Multihead attention을 적용하기 전에 normalization을 적용
  • 세로 한줄 한줄씩 정규화하여 감마와 베타값도 구함.
  • 이렇게 정규화한 값들을 가지고 멀티헤드 어텐션을 구함
  • 원본과 멀티헤드 어텐션으로 나온값을 더해준다.

 

 

4. Feed Forward

참조 (아래 더보기 클릭)

여기까지 싹하고나면, 아래 그림은 인코더 부분을 정리해서 나타낸 그림.

 

 

이것도 파라미터수가 feed forward후에 왜 4722432개 나오는 이유를 보자

 

'<개념> > Deep learning' 카테고리의 다른 글

What is Agent Force?  (0) 2024.11.03
LLAMA Inference  (0) 2024.05.17
T5 inference in inferentia  (0) 2024.04.08
openai gpt3 inference in inferentia2(neruon)  (0) 2024.03.28
GPT2 Text-generation을 AWS환경의 GPU/CPU/Inf2/Trn1에서..  (1) 2024.01.29

LLAMA 너무 커서 inf2.24large에서 시작하기 (허깅 페이스 토큰도 만들어야함)

AMI : Deep Learning AMI Neuron PyTorch 1.13 (Ubuntu 20.04) 20231003

source /opt/aws_neuron_venv_pytorch/bin/activate
pip3 install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com
pip3 install optimum
pip3 install -U "huggingface_hub[cli]"
huggingface-cli login

 

llama 사용권한요청1 : https://llama.meta.com/llama-downloads/

llama 사용권한요청2 : https://huggingface.co/meta-llama/Llama-2-7b-hf

코드1

from transformers import AutoTokenizer, LlamaForCausalLM
from huggingface_hub import login

login("본인 허깅페이스 토큰~")

model = LlamaForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

prompt = "Hey, are you conscious? Can you talk to me?"
inputs = tokenizer(prompt, return_tensors="pt")

# Generate
generate_ids = model.generate(inputs.input_ids, max_length=30)
output = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
print(output)

코드2

import time
import torch
from transformers import AutoTokenizer
from transformers_neuronx import LlamaForSampling
from huggingface_hub import login

login("본인토큰")
  
# load meta-llama/Llama-2-13b to the NeuronCores with 24-way tensor parallelism and run compilation
neuron_model2 = LlamaForSampling.from_pretrained('meta-llama/Llama-2-7b-chat-hf', batch_size=1, tp_degree=12, amp='f16')
neuron_model2.to_neuron() 

# construct a tokenizer and encode prompt text
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf")

prompt = ["Hello, I'm a language model,"]
#input_ids = tokenizer.encode(prompt, return_tensors="pt")
encoded_input = tokenizer(prompt, return_tensors='pt')

# run inference with top-k sampling
with torch.inference_mode():
    start = time.time()
    generated_sequences = neuron_model2.sample(encoded_input.input_ids, sequence_length=128, top_k=50)
    elapsed = time.time() - start

generated_sequences = [tokenizer.decode(seq) for seq in generated_sequences]
print(f'generated sequences {generated_sequences} in {elapsed} seconds')

https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/pytorch/torch-neuronx/t5-inference-tutorial.html

source /opt/aws_neuron_venv_pytorch/bin/activate
pip install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com
pip install --upgrade transformers==4.31.0 optimum-neuron==0.0.8
pip install torch_xla

AMI는

코드는 아래 더보기 누르기~

더보기
import torch
import datetime


from transformers.models.t5.modeling_t5 import T5Stack, T5LayerCrossAttention

class EncoderWrapper(torch.nn.Module):
    '''
        We will trace an instance of the EncoderWrapper.
        This wrapper just converts positional args to kwargs.
    '''

    def __init__(self,
                 encoder,
                 decoder,
                 model_config,
                 batch_size,
                 max_length,
                 device,
                 num_beams,
                 tp_degree=None):

        super().__init__()
        self.encoder = encoder
        self.decoder = decoder
        self.batch_size = batch_size
        self.max_length = max_length
        self.model_config = model_config
        self.device = device
        self.num_beams = num_beams
        self.num_attention_heads_per_partition = model_config.num_heads
        self.tp_degree = tp_degree

    def forward(self, input_ids, attention_mask):
        '''
            This is the core functionality we want to trace.
        '''
        encoder_output =  self.encoder(input_ids=input_ids,
                                       attention_mask=attention_mask,
                                       output_attentions=False,
                                       output_hidden_states=False)

        last_hidden_state = encoder_output["last_hidden_state"]
        encoder_hidden_states = torch.concat([tensor.unsqueeze(0).repeat(self.num_beams, 1, 1) for tensor in last_hidden_state])

        decoder_blocks = self.decoder.block
        present_key_value_states_sa = []
        present_key_value_states_ca = []

        for i, block in enumerate(decoder_blocks):

            # Cross attention has to be initialized with the encoder hidden state
            cross_attention: T5LayerCrossAttention = block.layer[1]
            attention = cross_attention.EncDecAttention

            def shape(states):
                """projection"""
                return states.view(self.batch_size, -1, self.num_attention_heads_per_partition, attention.key_value_proj_dim).transpose(1, 2)

            key_states = shape(attention.k(encoder_hidden_states))
            value_states = shape(attention.v(encoder_hidden_states))

            # cross_attn_kv_state
            present_key_value_states_ca.append(key_states)
            present_key_value_states_ca.append(value_states)

            # Self attention kv states are initialized to zeros. This is done to keep the size of the kv cache tensor constant.
            # The kv cache will be an input to the decoder trace. Any traced function will have a fixed control flow. What this means
            # is that the trace performs the exact same computations on inputs of the same shape in each invocation. So the attention
            # kv cache is padded here to keep a fixed shape.
            present_key_value_states_sa.append(torch.zeros((self.batch_size,                                                     # key states
                                                            self.model_config.num_heads,
                                                            self.max_length-1,
                                                            self.model_config.d_kv), dtype=torch.float32, device=self.device))
            present_key_value_states_sa.append(torch.zeros((self.batch_size,                                                     # value states
                                                            self.model_config.num_heads,
                                                            self.max_length-1,
                                                            self.model_config.d_kv), dtype=torch.float32, device=self.device))

        return present_key_value_states_sa + present_key_value_states_ca


class DecoderWrapper(torch.nn.Module):

    def __init__(self,
                 decoder: T5Stack,
                 lm_head: torch.nn.Linear,
                 model_config,
                 num_beams: int,
                 max_length: int,
                 device: str,
                 tp_degree=None):
        super().__init__()
        self.decoder = decoder
        self.lm_head = lm_head
        self.model_dim=model_config.d_model
        self.device = device
        self.num_beams = num_beams
        self.batch_size = 1
        self.config = model_config

        num_heads=model_config.num_heads
        num_decoder_layers=model_config.num_decoder_layers

        self.num_attention_heads_per_partition = num_heads

        # (num_beams, n_heads, seq_length, dim_per_head)
        if device == "cpu":
            self.past_key_values_sa = [torch.ones((num_beams,num_heads,max_length-1,model_config.d_kv), dtype=torch.float32) for _ in range(num_decoder_layers * 2)]
            self.past_key_values_ca = [torch.ones((num_beams,num_heads,max_length,model_config.d_kv), dtype=torch.float32) for _ in range(num_decoder_layers * 2)]
        elif device == "xla":
            self.past_key_values_sa = torch.nn.ParameterList([torch.nn.Parameter(torch.ones((num_beams,self.num_attention_heads_per_partition,max_length-1,model_config.d_kv), dtype=torch.float32), requires_grad=False) for _ in range(num_decoder_layers * 2)])
            self.past_key_values_ca = torch.nn.ParameterList([torch.nn.Parameter(torch.ones((num_beams,self.num_attention_heads_per_partition,max_length,model_config.d_kv), dtype=torch.float32), requires_grad=False) for _ in range(num_decoder_layers * 2)])

    def update_past(self, past_key_values):
        new_past_sa = []
        new_past_ca = []
        for past_layer in past_key_values:
            new_past_layer = list(past_layer)
            for i in range(len(new_past_layer[:2])):
                new_past_layer[i] = past_layer[i][:, :, 1:]
            new_past_sa += [new_past_layer[:2],]
            new_past_ca += [new_past_layer[2:],]
        return new_past_sa, new_past_ca

    def reorder_cache(self, past_key_values, beam_idx):
        for i in range(len(past_key_values)):
            gather_index = beam_idx.view([beam_idx.shape[0],1,1,1]).expand_as(past_key_values[i])
            past_key_values[i] = torch.gather(past_key_values[i], dim = 0, index=gather_index)
        return past_key_values

    def forward(self,
                input_ids,
                decoder_attention_mask,
                encoder_hidden_states,
                encoder_attention_mask,
                beam_idx,
                beam_scores,
                **kwargs):

        if self.num_beams > 1:
            # We reorder the cache based on the beams selected in each iteration. Required step for beam search.
            past_key_values_sa = self.reorder_cache(self.past_key_values_sa, beam_idx)
            past_key_values_ca = self.reorder_cache(self.past_key_values_ca, beam_idx)
        else:
            # We do not need to reorder for greedy sampling
            past_key_values_sa = self.past_key_values_sa
            past_key_values_ca = self.past_key_values_ca

        # The cache is stored in a flatten form. We order the cache per layer before passing it to the decoder.
        # Each layer has 4 tensors, so we group by 4.
        past_key_values = [[*past_key_values_sa[i*2:i*2+2], *past_key_values_ca[i*2:i*2+2]] for i in range(0, int(len(past_key_values_ca)/2))]

        decoder_output = self.decoder(
            input_ids=input_ids,
            attention_mask=decoder_attention_mask,
            past_key_values=past_key_values,
            encoder_hidden_states=encoder_hidden_states,
            encoder_attention_mask=encoder_attention_mask,
            use_cache=True,
            output_attentions=False,
            output_hidden_states=False)

        last_hidden_state = decoder_output['last_hidden_state']
        past_key_values = decoder_output['past_key_values']

        if self.config.tie_word_embeddings:
            # Rescale output before projecting on vocab
            # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586
            last_hidden_state = last_hidden_state * (self.model_dim**-0.5)

        lm_logits = self.lm_head(last_hidden_state)

        past_key_values_sa, past_key_values_ca = self.update_past(past_key_values)

        # We flatten the cache to a single array. This is required for the input output aliasing to work
        past_key_values_sa = [vec for kv_per_layer in past_key_values_sa for vec in kv_per_layer]
        past_key_values_ca = [vec for kv_per_layer in past_key_values_ca for vec in kv_per_layer]

        if self.device == "cpu":
            self.past_key_values_sa = past_key_values_sa
            self.past_key_values_ca = past_key_values_ca

        # We calculate topk inside the wrapper
        next_token_logits = lm_logits[:, -1, :]

        if self.num_beams > 1:
            # This section of beam search is run outside the decoder in the huggingface t5 implementation.
            # To maximize the computation within the neuron device, we move this within the wrapper
            logit_max, _ = torch.max(next_token_logits, dim=-1, keepdim=True)
            logsumexp = torch.log(torch.exp(next_token_logits - logit_max).sum(dim=-1, keepdim=True))
            next_token_scores = next_token_logits - logit_max - logsumexp
            next_token_scores = next_token_scores + beam_scores[:, None].expand_as(next_token_scores)

            # reshape for beam search
            vocab_size = next_token_scores.shape[-1]
            next_token_scores = next_token_scores.view(self.batch_size, self.num_beams * vocab_size)
            next_token_scores = next_token_scores * 1

            # Sample 2 next tokens for each beam (so we have some spare tokens and match output of beam search)
            next_token_scores, next_tokens = torch.topk(
                next_token_scores, 2 * self.num_beams, dim=1, largest=True, sorted=True
            )

            next_indices = torch.div(next_tokens, vocab_size, rounding_mode="floor")
            next_tokens = next_tokens % vocab_size

            return [next_token_scores, next_tokens, next_indices] + past_key_values_sa + past_key_values_ca
        else:
            # Greedy
            next_tokens = torch.argmax(next_token_logits, dim=-1)
            return [next_tokens] + past_key_values_sa + past_key_values_ca

import torch
import torch_xla.core.xla_model as xm

from transformers import T5Tokenizer, T5ForConditionalGeneration
from transformers.modeling_outputs import BaseModelOutput, Seq2SeqLMOutput
from transformers.models.t5.modeling_t5 import T5Stack, T5LayerCrossAttention
from transformers.generation.utils import ModelOutput
from typing import Any, Dict, List, Optional, Tuple, Union
from transformers.generation.beam_search import BeamScorer, BeamSearchScorer

from optimum.neuron.generation import NeuronGenerationMixin

from transformers.generation.logits_process import (
    LogitsProcessorList,
)
from transformers.generation.stopping_criteria import (
    MaxLengthCriteria,
    MaxTimeCriteria,
    StoppingCriteriaList,
    validate_stopping_criteria,
)

from transformers.generation.utils import (
    BeamSearchOutput,
    GreedySearchOutput,
)

class T5Wrapper(T5ForConditionalGeneration, NeuronGenerationMixin):

    def _prepare_encoder_decoder_kwargs_for_generation(
        self,
        inputs_tensor: torch.Tensor,
        model_kwargs,
        model_input_name: Optional[str] = None
    ) -> Dict[str, Any]:
        encoder = self.get_encoder()
        model_kwargs["encoder_outputs"]: ModelOutput = encoder(inputs_tensor, model_kwargs["attention_mask"])
        return model_kwargs

    # Override to cut the input_ids to just last token
    def prepare_inputs_for_generation(
        self,
        input_ids,
        past_key_values=None,
        attention_mask=None,
        head_mask=None,
        decoder_head_mask=None,
        decoder_attention_mask=None,
        cross_attn_head_mask=None,
        use_cache=None,
        encoder_outputs=None,
        **kwargs,
    ):
        # cut decoder_input_ids as past is cached
        input_ids = input_ids[:, -1:]

        return {
            "decoder_input_ids": input_ids,
            "past_key_values": past_key_values,
            "encoder_outputs": encoder_outputs,
            "attention_mask": attention_mask,
            "head_mask": head_mask,
            "decoder_head_mask": decoder_head_mask,
            "decoder_attention_mask": decoder_attention_mask,
            "cross_attn_head_mask": cross_attn_head_mask,
            "use_cache": use_cache,
        }

    '''
        We update the cache in the decoder trace, so lets override the _update_model_kwargs_for_xla_generation in NeuronGenerationMixin
    '''
    def _update_model_kwargs_for_xla_generation(
        self,
        model_kwargs: Dict[str, Any],
        batch_size: int,
        is_encoder_decoder: bool = False,
        standardize_cache_format: bool = False,
        max_length: Optional[int] = None,
        seq_length: Optional[int] = None,
        use_cache: bool = True,
    ) -> Dict[str, Any]:

        def _update_attention(model_kwargs, is_encoder_decoder):
            """Updates the appropriate attention mask -- encoder-decoder models use `decoder_attention_mask`"""

            attention_mask_name = "decoder_attention_mask" if is_encoder_decoder else "attention_mask"
            attention_mask = model_kwargs.pop(attention_mask_name)
            attention_mask_update_slice = torch.ones(
                (batch_size, 1), dtype=attention_mask.dtype, device=attention_mask.device
            )
            attention_mask = torch.cat([attention_mask[:, 1:], attention_mask_update_slice], dim=-1)
            mask = {attention_mask_name: attention_mask}
            return mask

        mask = _update_attention(model_kwargs, is_encoder_decoder)
        # sets the updated variables (mask and past_key_values)
        model_kwargs.update(mask)

        # Set a mock cache tensor
        model_kwargs["past_key_values"] = torch.tensor([])

        return model_kwargs

    def _reorder_cache(self, past_key_values, beam_idx):
        '''
            This is needed for beam search and not greedy sampling
            We reorder the cache within the trace so we can skip it in modelling_t5.py. So we override the _reorder_cache
        '''
        self.beam_idx = beam_idx
        return past_key_values

    def generate(self,
                tokenizer: T5Tokenizer,
                prompt: str,
                max_length: int,
                num_beams: int,
                num_return_sequences: int,
                device: str):

        batch_encoding = tokenizer(prompt, max_length=max_length, truncation=True, padding='max_length',
                                return_tensors="pt")

        past_key_values = self.encoder(batch_encoding['input_ids'],batch_encoding['attention_mask'])

        decoder_attention_mask = torch.cat([torch.zeros((1, max_length-1), dtype=torch.int32),
                                            torch.ones((1, 1), dtype=torch.int32)], axis=1)

        # copy the new cache state to the decoder
        if device == "xla":
            for state, tensor in zip(self.decoder.parameters(), past_key_values):
                state.copy_(tensor)
        else:
            # First half of the cache is self attention and the rest is cross attention
            self.decoder.past_key_values_sa = past_key_values[:len(past_key_values)//2]
            self.decoder.past_key_values_ca = past_key_values[len(past_key_values)//2:]

        output = super().generate(**batch_encoding,
                                max_length=max_length,
                                num_beams=num_beams,
                                num_return_sequences=num_return_sequences,
                                do_sample=False,
                                use_cache=True,
                                decoder_attention_mask=decoder_attention_mask,
                                encoder_outputs={"last_hidden_state": torch.ones((1,128,1))}) # Pass fake encoder_outputs so the transfomers code will not invoke the encoder
        return output

    def forward(
        self,
        attention_mask: Optional[torch.FloatTensor] = None,
        decoder_input_ids: Optional[torch.LongTensor] = None,
        decoder_attention_mask: Optional[torch.BoolTensor] = None,
        encoder_outputs: Optional[Tuple[Tuple[torch.Tensor]]] = None,
        beam_scores = None,
        **kwargs
    ) -> Union[Tuple[torch.FloatTensor], Seq2SeqLMOutput]:

        hidden_states = encoder_outputs["last_hidden_state"]

        if not hasattr(self, 'beam_idx'):
            # Infering the number of beams from the attention mask
            num_beams = attention_mask.shape[0]
            self.beam_idx = torch.arange(0, num_beams, dtype=torch.int64)

        decoder_outputs = self.decoder(
            decoder_input_ids,
            decoder_attention_mask,
            hidden_states,
            attention_mask,
            self.beam_idx,
            beam_scores
        )

        # lm_logits = decoder_outputs[0]
        next_token_scores = decoder_outputs[0]
        next_tokens = decoder_outputs[1]
        next_indices = decoder_outputs[2]

        return next_token_scores, next_tokens, next_indices

    def beam_search(
        self,
        input_ids: torch.LongTensor,
        beam_scorer: BeamScorer,
        logits_processor: Optional[LogitsProcessorList] = None,
        stopping_criteria: Optional[StoppingCriteriaList] = None,
        max_length: Optional[int] = None,
        pad_token_id: Optional[int] = None,
        eos_token_id: Optional[Union[int, List[int]]] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        output_scores: Optional[bool] = None,
        return_dict_in_generate: Optional[bool] = None,
        synced_gpus: Optional[bool] = False,
        seq_length: Optional[int] = None,
        **model_kwargs,
    ) -> Union[BeamSearchOutput, torch.LongTensor]:

        logits_processor = logits_processor if logits_processor is not None else LogitsProcessorList()
        stopping_criteria = stopping_criteria if stopping_criteria is not None else StoppingCriteriaList()
        pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id
        eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id
        if isinstance(eos_token_id, int):
            eos_token_id = [eos_token_id]
        output_scores = output_scores if output_scores is not None else self.generation_config.output_scores
        output_attentions = (
            output_attentions if output_attentions is not None else self.generation_config.output_attentions
        )
        output_hidden_states = (
            output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states
        )

        batch_size = len(beam_scorer._beam_hyps)
        num_beams = beam_scorer.num_beams

        batch_beam_size, cur_len = input_ids.shape

        # Overwrite cur_len
        cur_len = seq_length

        if num_beams * batch_size != batch_beam_size:
            raise ValueError(
                f"Batch dimension of `input_ids` should be {num_beams * batch_size}, but is {batch_beam_size}."
            )

        # init attention / hidden states / scores tuples
        scores = () if (return_dict_in_generate and output_scores) else None
        beam_indices = (
            tuple(() for _ in range(batch_beam_size)) if (return_dict_in_generate and output_scores) else None
        )

        # initialise score of first beam with 0 and the rest with -1e9. This makes sure that only tokens
        # of the first beam are considered to avoid sampling the exact same tokens across all beams.
        # beam_scores = torch.zeros((batch_size, num_beams), dtype=torch.float, device=input_ids.device)
        beam_scores_device = "cpu"
        beam_scores = torch.zeros((batch_size, num_beams), dtype=torch.float, device=beam_scores_device)
        beam_scores[:, 1:] = -1e9
        beam_scores = beam_scores.view((batch_size * num_beams,))

        while True:
            # prepare model inputs
            # From max_length-sized input_ids, select first
            # cur_len - 1 values.
            update_indices = torch.stack(
                [torch.arange(input_ids.size(0)), torch.tensor(cur_len - 1).repeat(input_ids.size(0))], dim=-1
            )
            input_ids_ = input_ids[update_indices[:, 0], update_indices[:, 1], None]
            model_inputs = self.prepare_inputs_for_generation(input_ids_, **model_kwargs)

            next_token_scores, next_tokens, next_indices = self(
                **model_inputs,
                return_dict=True,
                output_attentions=output_attentions,
                output_hidden_states=output_hidden_states,
                beam_scores=beam_scores
            )

            # stateless
            beam_outputs = beam_scorer.process(
                input_ids.to("cpu")[:, :cur_len],
                next_token_scores.to("cpu"),
                next_tokens.to("cpu"),
                next_indices.to("cpu"),
                pad_token_id=pad_token_id,
                eos_token_id=eos_token_id,
                beam_indices=beam_indices,
            )

            beam_scores = beam_outputs["next_beam_scores"]
            beam_next_tokens = beam_outputs["next_beam_tokens"]
            beam_idx = beam_outputs["next_beam_indices"]

            update_indices = torch.stack(
                [torch.arange(batch_beam_size), torch.tensor(cur_len - 1).repeat(batch_beam_size)], dim=-1
            )
            update_indices_2 = torch.stack(
                [torch.arange(batch_beam_size), torch.tensor(cur_len).repeat(batch_beam_size)], dim=-1
            )
            # First select beam_indices
            device = input_ids.device
            beam_idx_device = beam_idx.to(device=input_ids.device)
            input_ids[:, :] = input_ids[beam_idx_device.long(), :]

            # Then append new tokens
            input_ids[update_indices_2[:, 0], update_indices_2[:, 1], None] = beam_next_tokens.unsqueeze(-1).to(device).to(torch.long)
            input_ids = input_ids * 1  # Hack to materialize tensor

            # update generated ids, model inputs, and length for next step
            model_kwargs = self._update_model_kwargs_for_xla_generation(
                model_kwargs,
                batch_size=batch_beam_size,
                is_encoder_decoder=self.config.is_encoder_decoder,
                max_length=stopping_criteria.max_length,
                seq_length=cur_len,
                use_cache=model_kwargs["use_cache"],
            )
            if model_kwargs["past_key_values"] is not None:
                model_kwargs["past_key_values"] = self._reorder_cache(model_kwargs["past_key_values"], beam_idx.to(torch.int64))

            if return_dict_in_generate and output_scores:
                beam_indices = tuple((beam_indices[beam_idx[i]] + (beam_idx[i],) for i in range(len(beam_indices))))

            # increase cur_len
            cur_len = cur_len + 1

            # stop when each sentence is finished, or if we exceed the maximum length
            stop_criterion_1 = beam_scorer.is_done
            if isinstance(stopping_criteria, list):
                if len(stopping_criteria) == 1:
                    stopping_criteria = stopping_criteria[0]

            # Cases that can be handled in XLA without requiring
            # non-padded input_ids
            if isinstance(stopping_criteria, MaxLengthCriteria):
                stop_criterion_2 = cur_len >= stopping_criteria.max_length
            elif isinstance(stopping_criteria, MaxTimeCriteria):
                stop_criterion_2 = stopping_criteria(input_ids, scores)
            else:
                # Other cases will be handled on CPU
                batch_size, _ = input_ids.shape
                input_ids_cpu = input_ids.to("cpu")
                mask = torch.cat(
                    [torch.ones(batch_size, cur_len), torch.zeros(batch_size, input_ids.shape[1] - cur_len)], dim=1
                ).bool()
                input_ids_cpu = torch.masked_select(input_ids_cpu, mask).reshape((batch_size, cur_len))
                scores_cpu = scores.to("cpu") if torch.is_tensor(scores) else scores
                stop_criterion_2 = stopping_criteria(input_ids_cpu, scores_cpu)

            if stop_criterion_1 or stop_criterion_2:
                if not synced_gpus:
                    break
                else:
                    this_peer_finished = True

        sequence_outputs = beam_scorer.finalize(
            input_ids.to("cpu"),
            beam_scores.to("cpu"),
            next_tokens.to("cpu"),
            next_indices.to("cpu"),
            pad_token_id=pad_token_id,
            eos_token_id=eos_token_id,
            max_length=stopping_criteria.max_length,
            beam_indices=beam_indices,
        )

        for k, v in sequence_outputs.items():
            if type(v) == torch.Tensor:
                sequence_outputs[k] = sequence_outputs[k].to(input_ids.device)

        return sequence_outputs["sequences"]


    def greedy_search(
        self,
        input_ids: torch.LongTensor,
        logits_processor: Optional[LogitsProcessorList] = None,
        stopping_criteria: Optional[StoppingCriteriaList] = None,
        max_length: Optional[int] = None,
        pad_token_id: Optional[int] = None,
        eos_token_id: Optional[Union[int, List[int]]] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        output_scores: Optional[bool] = None,
        return_dict_in_generate: Optional[bool] = None,
        seq_length: Optional[int] = int,
        streamer: Optional["BaseStreamer"] = None,
        **model_kwargs,
    ) -> Union[GreedySearchOutput, torch.LongTensor]:
        """
            Overriding greedy sampling to use next tokens returned from neuron device instead of logits.
        """
        # init values
        logits_processor = logits_processor if logits_processor is not None else LogitsProcessorList()
        use_cache = model_kwargs["use_cache"] if "use_cache" in model_kwargs else False
        stopping_criteria = stopping_criteria if stopping_criteria is not None else StoppingCriteriaList()
        pad_token_id = pad_token_id if pad_token_id is not None else self.generation_config.pad_token_id
        eos_token_id = eos_token_id if eos_token_id is not None else self.generation_config.eos_token_id
        if isinstance(eos_token_id, int):
            eos_token_id = [eos_token_id]
        eos_token_id_tensor = torch.tensor(eos_token_id).to(input_ids.device) if eos_token_id is not None else None
        output_scores = output_scores if output_scores is not None else self.generation_config.output_scores
        output_attentions = (
            output_attentions if output_attentions is not None else self.generation_config.output_attentions
        )
        output_hidden_states = (
            output_hidden_states if output_hidden_states is not None else self.generation_config.output_hidden_states
        )

        # init attention / hidden states / scores tuples
        scores = () if (return_dict_in_generate and output_scores) else None
        decoder_attentions = () if (return_dict_in_generate and output_attentions) else None
        cross_attentions = () if (return_dict_in_generate and output_attentions) else None
        decoder_hidden_states = () if (return_dict_in_generate and output_hidden_states) else None


        # keep track of which sequences are already finished
        unfinished_sequences = torch.ones(input_ids.shape[0], dtype=torch.long, device=input_ids.device)

        this_peer_finished = False  # used by synced_gpus only
        while True:

            # prepare model inputs
            # From max_length-sized input_ids, select first
            # seq_length - 1 values.

            if model_kwargs.get("past_key_values") is None:
                input_ids_ = input_ids[:, :seq_length]
            else:
                update_indices = torch.stack(
                    [torch.arange(input_ids.size(0)), torch.tensor(seq_length - 1).repeat(input_ids.size(0))],
                    dim=-1,
                )
                input_ids_ = input_ids[update_indices[:, 0], update_indices[:, 1], None]

            model_inputs = self.prepare_inputs_for_generation(input_ids_, **model_kwargs)

            # forward pass to get next token
            output = self(
               **model_inputs,
                return_dict=True,
                output_attentions=output_attentions,
                output_hidden_states=output_hidden_states,
            )
            next_tokens = output[0]

            # finished sentences should have their next token be a padding token
            if eos_token_id is not None:
                if pad_token_id is None:
                    raise ValueError("If `eos_token_id` is defined, make sure that `pad_token_id` is defined.")
                next_tokens = next_tokens * unfinished_sequences + pad_token_id * (1 - unfinished_sequences)

            # update generated ids, model inputs, and length for next step

            batch_size, _ = input_ids.shape
            update_indices = torch.stack(
                [torch.arange(batch_size), torch.tensor(seq_length).repeat(batch_size)], dim=-1
            )
            input_ids[update_indices[:, 0], update_indices[:, 1]] = next_tokens[:]
            model_kwargs = self._update_model_kwargs_for_xla_generation(
                model_kwargs,
                batch_size=batch_size,
                is_encoder_decoder=self.config.is_encoder_decoder,
                max_length=stopping_criteria.max_length,
                seq_length=seq_length,
                use_cache=use_cache,
            )

            seq_length += 1

            # if eos_token was found in one sentence, set sentence to finished
            if eos_token_id_tensor is not None:
                unfinished_sequences = unfinished_sequences.mul(
                    next_tokens.tile(eos_token_id_tensor.shape[0], 1).ne(eos_token_id_tensor.unsqueeze(1)).prod(dim=0)
                )

            # stop when each sentence is finished, or if we exceed the maximum length
            stop_criterion_1 = unfinished_sequences.max() == 0

            if isinstance(stopping_criteria, list):
                if len(stopping_criteria) == 1:
                    stopping_criteria = stopping_criteria[0]

            # Cases that can be handled in XLA without requiring
            # non-padded input_ids
            if isinstance(stopping_criteria, MaxLengthCriteria):
                stop_criterion_2 = seq_length >= stopping_criteria.max_length
            elif isinstance(stopping_criteria, MaxTimeCriteria):
                stop_criterion_2 = stopping_criteria(input_ids, scores)
            else:
                # Other cases will be handled on CPU
                batch_size, _ = input_ids.shape
                mask = torch.cat(
                    [torch.ones(batch_size, seq_length), torch.zeros(batch_size, input_ids.shape[1] - seq_length)],
                    dim=1,
                ).bool()
                input_ids_cpu = torch.masked_select(input_ids, mask).reshape((batch_size, seq_length)).to("cpu")
                scores_cpu = scores.to("cpu") if torch.is_tensor(scores) else scores
                stop_criterion_2 = stopping_criteria(input_ids_cpu, scores_cpu)

            if stop_criterion_1 or stop_criterion_2:
                this_peer_finished = True

            if this_peer_finished:
                break

        if streamer is not None:
            streamer.end()

        return input_ids


# Let's set some run parameters

model_name = "t5-large"
num_beams = 1
num_return_sequences = 1
max_length = 128

from transformers import T5Tokenizer


prompt="translate English to German: Lets eat good food."

tokenizer = T5Tokenizer.from_pretrained(model_name, model_max_length=max_length)
model = T5Wrapper.from_pretrained(model_name)

model.encoder = EncoderWrapper(model.encoder, model.decoder, model.config, num_beams, max_length, "cpu", num_beams)
setattr(model.encoder, 'main_input_name', 'input_ids')  # Attribute required by beam search

model.decoder = DecoderWrapper(decoder=model.decoder,
                                lm_head=model.lm_head,
                                model_config=model.config,
                                num_beams=num_beams,
                                max_length=max_length,
                                device="cpu")
start = datetime.datetime.now()
output = model.generate(tokenizer=tokenizer,
                        prompt=prompt,
                        max_length=max_length,
                        num_beams=num_beams,
                        num_return_sequences=num_return_sequences,
                        device="cpu")
end = datetime.datetime.now()
total = end - start
print("Execution time: ", total)

results = [tokenizer.decode(t, skip_special_tokens=True) for t in output]

print('Results:')
for i, summary in enumerate(results):
    print(i + 1, summary)

 

여러개 인스턴스 중에서 되는걸로 사용하는법

그냥 인스턴스만들기한다음 기타 + 스팟 체크해서 사용하는 방법도 있움

 

 

1. 템플릿 만든다. (AMI 설정/키페어/보안그룹/스토리지 등등)

2. 스팟 생성하기에서  템플릿 선택하고, 네트워크-가용영역-서브넷 설정 (서브넷 설정에서 private 안되게 지정해준다. private 서브넷 선택되면 ssh 안드가짐)

3. 인스턴스 유형 선택하기 ( inf2.xlarge를 사용하고 싶을땐 inf2.xlarge선택하고, 나머지는 그거보다 큰걸로 설정해놓으면 됨)

'<Cloud> > AWS' 카테고리의 다른 글

AWS Sagemaker Studio Data Wangler 실습  (0) 2022.12.27
[EC2 CLI] aws ec2 run-instances  (0) 2022.07.11
AWS 보안서비스 종류들  (0) 2022.05.19
AWS ECS 간단이해  (0) 2022.05.18
Lamdba Cold start 예방하는 방법 2가지  (0) 2022.05.18
import openai

openai.api_key = 'mykey'

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": "Hello, I'm a language model,"}
    ]
)
print(response['choices'][0]['message']['content'])

 

< setting>

AMI : Deep Learning AMI Neuron PyTorch 1.13 (Ubuntu 20.04) 20240102

인스턴스 : Inf2.xlarge

source /opt/aws_neuron_venv_pytorch/bin/activate

pip install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com

python3 sample.py

 

 

**코드 참조 : https://platform.openai.com/docs/guides/rate-limits/error-mitigation?context=tier-free 

**코드 참조 2 : 챗지피티4

** openai에서 사용가능한 모델 : https://platform.openai.com/docs/models/overview

첨에 RateLimitError 에러가 나서 limit 확인

https://platform.openai.com/docs/guides/rate-limits/usage-tiers?context=tier-free

 

RateLimitError 해결해볼라고 14000원 결제도 함..

1. GPU / CPU

 

GPU AMI : 

 

CPU AMI : 그냥 ubuntu 20.0 서버

 

참조 : https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-generation

sudo apt-get update
pip3 install accelerate
pip3 install transformers
pip3 install torch
git clone https://github.com/huggingface/transformers.git

cd transformers/examples/pytorch/text-generation

python3 run_generation_inf2.py --model_type gpt2 --model_name_or_path gpt2 --num_return_sequences 1 --prompt="“Hello, I’m a language model,”:" --temperature 0.7

 **  --model_name_or_path gpt2 이부분을 gpt2, gpt2-medium, gpt2-large, gpt2-xl, openai-gpt 로 바꿔줄 수 있음

 

2. Inf2.xlarge / Trn1.2xlarge

 

AMI : Neruon + Pytorch + ubuntu 20.0 조합 아무거나

( Deep Learning AMI Neuron PyTorch 1.13 (Ubuntu 20.04) 20240102 )

참조 : https://awsdocs-neuron.readthedocs-hosted.com/en/latest/libraries/transformers-neuronx/transformers-neuronx-developer-guide.html

source /opt/aws_neuron_venv_pytorch/bin/activate
pip install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com
from transformers_neuronx.gpt2.model import GPT2ForSampling
from transformers_neuronx.generation_utils import HuggingFaceGenerationModelAdapter
from transformers_neuronx.module import save_pretrained_split
from transformers import AutoModelForCausalLM, AutoTokenizer
import datetime

# Load and save the CPU model
model_cpu = AutoModelForCausalLM.from_pretrained('gpt2-xl')
save_pretrained_split(model_cpu, 'gpt2-split')

# Create and compile the Neuron model
model_neuron = GPT2ForSampling.from_pretrained('gpt2-split', batch_size=1, tp_degree=2, n_positions=256, amp='f32', unroll=None)
model_neuron.to_neuron()

# Use the `HuggingFaceGenerationModelAdapter` to access the generate API
model = HuggingFaceGenerationModelAdapter(model_cpu.config, model_neuron)

# Get a tokenizer and exaple input
tokenizer = AutoTokenizer.from_pretrained('gpt2-xl')
tokenizer.pad_token_id = tokenizer.eos_token_id
tokenizer.padding_side = 'left'
text = "Hello, I'm a language model,"
encoded_input = tokenizer(text, return_tensors='pt', padding=True)

# Run inference using temperature
model.reset_generation()
start = datetime.datetime.now()
sample_output = model.generate(
    input_ids=encoded_input.input_ids,
    attention_mask=encoded_input.attention_mask,
    do_sample=True,
    max_length=20,
    temperature=0.7,
)
end = datetime.datetime.now()
total = end - start
print("Execution time: ", total)
print([tokenizer.decode(tok) for tok in sample_output])

위 코드 포함하는 sample.py 생성

** 저 코드에서 gpt2-xl 이부분도 gpt2, gpt2-medium, gpt2-large, gpt2-xl 로 바꿔줄수 있음

Python3 sample.py

 

 

첫번째시도(실패)

- hugging face에서 제공하는 pytorch 코드로 돌리면 손을좀 봐야한다. 이유는 해당코드가 gpu/cpu 전용으로 만들어졌기 때문. 

( https://github.com/huggingface/transformers/blob/main/examples/pytorch/text-generation/run_generation.py )

- torch.jit.trace와 torch_neuron.trace는 모두 PyTorch 모델을 최적화하여 pytorch 모델을 TorchScript로 바꿔주는데 사용함. 그런데 전자는 cpu/gpu 용도이고 후자가 inferentia용으로 Nueron 호환 형식으로 변환. 그래서 후자로 변환해줘야함

- 변환해줘도 뉴런코어의 사용률이 0%

 

두번째시도(성공)

- hugging face 를 베이스로한 다른 추론코드를 찾음. 뉴런코어를 잘 사용함. ( https://awsdocs-neuron.readthedocs-hosted.com/en/latest/libraries/transformers-neuronx/transformers-neuronx-developer-guide.html )

- 사용한 aws ami : AMI : Deep Learning AMI Neuron PyTorch 1.13 (Ubuntu 20.04) 20240102

- 아래 실행해주면됨.

# 참조 : https://github.com/aws-neuron/transformers-neuronx
pip install transformers-neuronx --extra-index-url=https://pip.repos.neuron.amazonaws.com
source /opt/aws_neuron_venv_pytorch/bin/activate
python3 sample.py

- 모니터링 참조는 https://awsdocs-neuron.readthedocs-hosted.com/en/latest/tools/neuron-sys-tools/neuron-monitor-user-guide.html

neuron-monitor -c monitor.conf >> output.json

 

Luminol을 알려면 Bitmap이 뭔지를 알아야함 (깃허브 살펴보면, bitmap 논문 참조했다고 주석에 나옴 http://alumni.cs.ucr.edu/~ratana/KumarN.pdf)

<1차이해>

우선 Bitmap은 카오스게임방식으로 패턴을 나타낸다. 이것은 단순한 숫자를 문자로 변환하여 패턴을 한눈에 살펴볼수 있도록 하는 알고리즘입니다. 하지만 이 알고리즘을 적용하기위해서는 이산 시퀀스형태로 만들어야하는데 우리가 사용하고자 하는 데이터는 시계열 실수 데이터. 이런 시계열 데이터를 이산 시퀀스로 변환해주는것이 바로 SAX알고리즘입니다 SAX 알고리즘은 타임시리즈 실수 데이터를 동일한 크기의 구간으로 나눕니다. 나눈 구간의 평균값을 계산한다음 그 구간을 전부다 그 평균값으로 대체해버리는 방식으로 타임시리즈 데이터를 이산시퀀스로 변환해줍니다. 그리하여 연속된 실수값 타임시리즈값을 → 일정 구간으로 나누어 평균값으로 바꾸어버려 이산시퀀스로 만들고 → 구간별로 baabccbc같은 문자로 패턴을 얻을수 있다. → 얻어낸 문자패턴을 카오스게임에 적용하여 시각화할수 있습니다.

anomaly detection을 하는방법은 다음과 같습니다. 1) 타임시리즈는 lead 윈도우와 lag 윈도우로 나뉜다. 두개의 크기는 다를수 있으며 lead window는 예측하고자하는 window, lag window는 선행 윈도우로 대체적으로 lead window이전의값을 의미합니다. 이 각각의 window에 속한 타임시리즈는 앞에서처럼 sax알고리즘을 사용하여 문자열로 바꾸고 → 문자열로 바꾼값을 quad tree안에 집어넣어서 정리하여 두개의 bitmap를 생성합니다.→ 두개 비트맵사이의 거리는 아래식으로 구합니다. (이 구한 숫자가 바로 이상탐지값이고, 이 숫자 높을수록 이상치값이 높다고 판단합니다.) 이 과정을 쭉 반복하면서 이상치값을 구하고 새롭게 구한 이상치값으로 재구성한 그래프를 내놓은게 바로 luminol 입니다.

 

코드를 살펴본결과 Luminol울 수행할때 lead window, lag window 의 디폴트 크기는 전체 데이터 길이의 0.2/16 즉 약 1.25% 를 차지하도록 설정해줍니다. 그리고 너무 작은 데이터사이즈나 너무 큰 데이터 사이즈의 경우를 대비해서 min,max사이즈도 정해두었습니다. 아래코드처럼 chunk_size(=윈도우크기)를 사용자가 직접 설정하지 않으면 디폴트값으로 진행되는것으로 확인하였습니다.

그리고 lag window와 future_window(=lead window)값을 비교하는 함수를 살펴보니 위논문에서 구한 식과 동일한것을 확인하였습니다.

 

<2차이해>

 

더욱 구체적인 예제로는 https://www.researchgate.net/publication/249889424_Time-series-bitmap_Based_Approach_to_Analyze_Human_Postural_Control_and_Movement_Detection_Strategies_during_Small_Anterior_Perturbations 논문과, luminol github에서 참조하였다는 bitmap논문의 이전버전 논문인 http://alumni.cs.ucr.edu/~ratana/KumarN.pdf 를 참조하였습니다.

  1. 슬라이딩 윈도우방식으로 타임시리즈데이터를 처음부터 2개윈도우창으로 나누어서 끝까지 훝는다. 2개 window는 Lag window와 Lead window(github에서는 future 윈도우)
  2. SAX알고리즘을 통해 타임시리즈 데이터를 문자열로 만들어줍니다. (연속된 실수를 일정단위별로 끊어서 평균값을 구하고 계단형으로 변환, 그 변환된것을 문자열로 변경
  3. 아래 예제에서는 4*4 크기 윈도우를 사용하였고 aaaaaaaa에서 aa가 8개 존재하기 때문에 aa항에 7을 넣어줍니다. aaaa의 경우는 aa가 3개 있기 때문에 aa항에 3을 넣어줍니다.
  4. 이 윈도우를 0-1사이의값으로 변환해줍니다. 왼쪽 figure에서는 0-white, 1-black으로 변환해준다라고 표현하였고, 오른쪽 figure에서는 normalize한다라고 표현하였습니다.
  5. 0-1로 재구성한 4*4그래프 2개값을 가지고 score를 구합니다. 오른쪽 figure를 기준으로 살펴보면 aaaaaaaa 와 aaa의 차이는(lagwindow-futurewindow)^2로 구하며 (1-1)^2=0으로 anomaly score이 0입니다.

github에서 소개하는 bitmap 논문의 이전 버전 논문을 찾아낸본결과(http://alumni.cs.ucr.edu/~ratana/KumarN.pdf) normalize해서 색깔별로 나타내보면 다음과같이 비슷한 타임시리즈 데이터일수록 매우 흡사한 컬러배치를 보인다는것을 알수 있습니다.

moving average가 가장 평균적으로 많이 쓰이는 smoothing 방식입니다. 이는 주어진 데이터 전/후의 일정 개수의 데이터의 평균이나 중간값을 그 데이터의 값으로 추정하는 방법입니다. 그에 반해 savgol filter은 특정구간의 평균/중간값이 아니라, 특정구간을 ax^2 + bx + c 같은 회귀모델을 이용한 smoothing을 수행합니다.

xi의 새로운 값은 양쪽 근방 2n+1 개의 점으로 다항식 회귀한 식으로부터 다시 추정해 내는 것이 핵심 아이디어입니다. 즉, xi 를 포함하고 있는 양쪽 근방 2n+1 개의 점으로 다항식 회귀한 식 Si을 찾고, Si(xi)로 xi 를 대체하는 것입니다. (** 2n+1인이유는 오른쪽으로 n개, 왼쪽으로 n개 , xi 1개해서 2n+1로 셉니다. 그래서 윈도우 갯수는 홀수입니다.) 아래 그림을 예제로 들면 25값을 기준으로 오른쪽으로3개 왼쪽으로3개값을 떼서 7개 데이터를 윈도우로 떼서 봅니다. 7개데이터를 가지고 회귀곡선을 새롭게 그린다음 25에 해당하는 Y값을 새로이 지정해줍니다.

여기서 가장 큰 문제는 xi를 구하기위해 앞뒤 데이터들을 합친 2n+1개 윈도우를 떼서 새로이 다항회귀식(si)를 재구성하는것입니다.

(출처 : https://eigenvector.com/wp-content/uploads/2020/01/SavitzkyGolay.pdf)

Si 회귀함수를 구하고, 그에 맞는 새로운값을 구하는과정은 아래와같이 구해질수 있습니다.

 

  • 모든 괄호앞에는 빈칸
  • , , , and
  • , 이거쓸때 공백 꼭!!!!
  • Abstract는 보통 마지막에씀
  • 학회별로 템플릿 꼭 확인할것 (https://www.ieee.org/conferences/publishing/templates.html)
  • 단락별로 필수내용을 쓰고 거기에 살을 붙이는 식으로 진행
  • 풀네임 (약어) ex) Amazon Web Service (AWS)
  • 갈호칠땐 꼭 공백 포함 ex) aws (블라블라)
  • 영어번역은 파파고 구글보다 chatgpt4.0이 가장 자연스럽고 매끄럽다
  • motivation 같은 직접적인 제목은 피하기
  • introduction에서 figure 참조는 하지않음

(피드백받은 부분)

  • 일반적인 이야기를 시작으로 구체적인 예제를 드는 방향으로 작성할것
  • 예측 모델, 입출력 데이터 등은 가능하면 수식등을 사용해서 정의하기 - https://github.com/soulmachine/machine-learning-cheat-sheet/
  • 실험결과 작성시 이미지 및 테이블의 위치가 텍스트와 최대한 매치 되도록 할것 (설명하는 페이지보다 두페이지 뒤에가있으면 리뷰어들이 얼탱이가 없을듯)
  • 테이블, 그림 작성시 복사-붙여넣기 하면 라벨 바꾼것 꼭꼭 확인!!!!!!!
  • 그림 설명 작성시에는 각 축에 있는 값을 설명하는것이 기본중의 기본. (x값은 뭐고 세로값은 뭐고 점찍은건 뭐고...)
  • 실험 결과 작성 시 단순히 그래프에 있는 숫자를 나열하는 것 보다는 그 이유에 대한 깊이 있는 분석이 추가 되어야 한다.(단순하게 표를 읽는건 완전 비추)
  • 기본틀, 템플릿 다운받기

https://template-selector.ieee.org/secure/templateSelector/publicationType

  • Figure 가로 꽉차게
더보기
\begin{figure*}
    \centering
    \includegraphics[width=0.95\textwidth]{figures/architecture_overall_figure.pdf}
    \caption{example}
    \label{fig:architecture_overall_figure}
\end{figure*}
  • Figure 1/2 행
더보기
\begin{figure}
    \centering
    \includegraphics[width=0.45\textwidth]{figures/architecture_overall_figure.pdf}
    \caption{example}
    \label{fig:architecture_overall_figure}
\end{figure}
  • 한글사용
더보기
%한글사용을 위해 추가
\usepackage{kotex}
  • 표그리기
더보기
\begin{table}
    \def\arraystretch{1.05}
    \centering
    {\tiny
        \begin{tabular}{ |c||c|c|c|c|c|c|  }
         \hline
         \multicolumn{7}{|c|}{example} \\
         \hline
         hoho & 1 & 2 & 3 & 4 & 5 & 6\\
         \hline
         \hline
         name & a & a & a & a & a & a
         \\ %change base to boost clock
        \hline
         Compute capability  & d & a  & d & d & e & f \\
         Released Year & 2017 & 2019 & 2021 & 2017 & 2020 & 2021 \\
         \hline
        \end{tabular}
    \caption{example}
    \label{tab:example}
    }
\end{table}
  • section, subsection
더보기
\section{Introduction}\label{sec:introduction}

\subsection{model}\label{ch:model}
  • 점점이 리스트
더보기
\begin{itemize}
\item{점1}
\item{점2}
\item{점3}
\end{itemize}
  • 줄임말 주석처리
더보기
CC\footnote{Compute Capacity}
% 주석달기1
{\footnotesize \textsuperscript{1}CC: Compute Capacity}
% 주석달기2
\multicolumn{4}{l}{$^{\mathrm{1}}$Compute Capacity}
  • Reference
더보기
\bibliographystyle{unsrt} #reference 스타일
\bibliography{bibtex-share.bib} #reference해줄 bib파일
  • 한 figure에 vertical subfigure
더보기
\begin{figure}
    \centering
    \subfloat[Relative Latency per Model]{
        \includegraphics[width=0.45\textwidth]{figures/DRAMA_figure.pdf}
        \label{fig:DRAMA_figure}
    } % 이거진짜 중요한데 띄어쓰기 subfloat끼리 띄어쓰기안하면 vertical아니로 세로로 붙어서 에러남...
    %아마 띄우지않고 붙이면 한개의 figure로 취급하는거같음
    
    
    \subfloat[Relative Cost per Model]{
        \includegraphics[width=0.45\textwidth]{figures/DRAMA_luminol_figure.pdf}
        \label{fig:DRAMA_luminol_figure}
    }
    
    \subfloat[Relative Cost per Model]{
        \includegraphics[width=0.45\textwidth]{figures/DRAMA_savgol_figure.pdf}
        \label{fig:DRAMA_savgol_figure}
    }
\caption{example}
\label{fig:
  • Table안에서 줄바꿈
더보기
1. \newline
2. & \makecell[l]{SMACT \\   SMOCC} 이런식으로 셀1개안에 또 셀을 만들어줌

+ Recent posts