디컴파일이란 기계어를 사람의 코드로 번역하는 과정이다.
예전에 학부 시절에 잠시 어셈블리를 배웠던 적이 있는데, 이 어셈블리 코드로부터 고수준 코드(파이썬, C, C++같은)로 변환하는 과정을 디컴파일이라고 한다.
예-전 학부때 배웠던 것을 떠올려 보자면 원래 코드는 다음과 같은 과정으로 만들어진다.
(블록 코딩 ->) 고수준 언어(C, java, python, ruby, scalar, ...)로 코드 작성 -> 저수준 코드 -> 바이너리
고수준 언어에서 저수준 언어로 우선 컴파일을 진행하고, 컴파일된 코드를 컴퓨터가 실행할 때 알아서 바이너리로 해석된다. 그래서 파이썬 같은 인터프리터 기반 코드 말고 컴파일러가 붙은 자바나 C 같은 경우 한 번 코드를 컴파일한 뒤 사용한다.
그럼 왜 디컴파일을 해야 되는가? 찾아보니 다음과 같은 이유들이 있다고 한다.
transformer를 활용한 모델은 존재했었다고 한다. 그러나 현재 LLM의 정확도나 비-hallucination 정도가 많이 올라간 상황에서, 해당 구조를 사용하여 디컴파일을 할 수 있겠다는 생각이 들어 LLM에 디컴파일 데이터를 먹였다고 한다.
큰 모델 학습용 데이터를 잘 만들었다.
우선 코드 페어 자체는 Anghabench라는 compilable c 파일 public collection을 통해 만들었다고 한다.
(잘 모르지만) 컴파일 시 optimization level이라는 것이 존재한다고 한다. 보통 O0(no optimization)에서 O3(Agressive optimization - 대신 시간이 오래 걸린다고 함)까지 존재하는데, 이를 코드마다 프롬프트에 태그처럼 달아서 모델이 해당 optimization level에 따라 다르게 생성하도록 했다고 한다.
데이터는 이렇게 만들고, 학습할 때 objective를 실험을 통해 결정했다.
보통 language model의 경우 모델의 형태에 따라 세 가지 objective가 생긴다.
사실 굳이 타고들어가면 더 있지만, 일단 기본적으로 1 -> bert 2 -> T5 3 -> CLM 이다. (사실 T5같은 인코더-디코더 모델은 1,2가 동시에 있다)
여하튼 입출력이 asm -> src(src code) 인 것이니 1은 제외하고 2와 3중에 training objective 를 고른다.
2를 선택할 경우 src가 라벨이 되고, 3을 선택할 경우 asm+src가 라벨이 된다.
실험을 통해 2를 사용하는 것이 가장 도움이 되었다는 것을 밝혔다
sts랑 ntp를 같이 사용할 수 있지만 재컴파일에서 실패할 가능성이 더 컸기 때문에 적합하지 않았다고 판단했다.