Software2.0 by Andrew Karpathy(2017)
이 글은 테슬라의 CTO였던 Andrew Karpathy가 2017년에 쓴 Software 2.0이라는 글이다. 2017년 작성 당시, Andrew Karpathy가 뉴럴 네트워크에 대해서 어떤 생각을 가지고 있는지, 5년이 지난 지금 2022년에 뉴럴 네트워크는 어떻게 변화되었는지, 그리고 앞으로는 또 어떻게 변화할지 고민하면서 글을 번역해보려고 한다.
소프트웨어 2.0
나는 사람들이 뉴럴넷을 ‘머신러닝 툴박스 중 하나’라고 소개하는 것을 가끔씩 보곤한다. 뉴럴넷은 그만의 장점과 단점이 존재하고, 여기 저기에 쓰이며, 캐글 컴피티션 우승을 위해 사용되기도 한다. (지금은 캐글 컴피티션에 뉴럴넷을 사용하는 것이 보편적인 일이지만, 2017년 당시에는 그다지 보편적이진 않았나보다.)
불행히도, 그들의 이해는 나무만 보고 숲은 보지 못하는 것과 같다. 뉴럴넷은 그저 또 다른 분류기가 아니라 우리가 소프트웨어를 개발하는데 있어서 근본적인 변환을 일으킬 시작점이다. 뉴럴넷은 소프트웨어 2.0이다.
소프트웨어 1.0의 전통적인 “기술 스택”은 모두가 잘 알고 있다. 파이썬, C++과 같은 언어로 작성되어있으며, 프로그래머에 의해서 직접적인 명시로 이루어져있다. 코드의 라인들을 한줄 한줄 작성하면서 프로그래머는 자신의 의도를 프로그램 스페이스에 명시해야한다.
반면에, 소프트웨어 2.0은 뉴럴넷의 가중치들과 같이 훨씬 추상적이고 인간에게 친화적이지 않은(human-unfriendly) 언어로 작성된다. 뉴럴넷은 너무나 많은 가중치로 이루어져 있기 때문에 (보통 수백만 개의 가중치로 구성된다) 어떤 인간도 이런 코드를 작성하는 것은 불가능하다.(필자가 시도해봄)

대신에, 우리는 의도한 프로그램의 행동에 어떠한 목표를 상세해주고(e.g. ‘인풋 아웃풋예시를 충족하는’, 또는 ‘바둑 게임을 이기는’ 등의), 서칭할 프로그램 스페이스의 부분집합(subset)을 명시하는 코드 골격(rough skeleton)을 작성하며(i.e. 뉴럴넷 아키텍쳐와 같은), 또 이 프로그램 스페이스를 찾는데 연산 리소스들을 사용하여 프로그래밍 목표를 달성한다. 뉴럴넷의 경우, 이 서칭 과정을 역전파와 SGD(stochastic gradient descent)와 함께 효과적으로 이루어질 수 있는 프로그램 스페이스의 연속적인 부분집합을 찾는 것으로 제한한다.

이 비교를 더 구체적으로 하기 위해서, 사람이 직접 소스코드를 엔지니어링하는 소프트웨어 1.0(e.g. .cpp 파일들)에서는 바이너리 파일로 컴파일된다. 소프트웨어 2.0에서는 소스코드는 1)목표하는 행동 양상을 정의하는 데이터셋들과 2)대략적인(많은 디테일이 채워져야하는) 코드 골격을 제공하는 뉴럴넷 아키텍쳐로 이루어져있다. 최종적인 뉴럴넷을 컴파일하기 위해서는 데이터셋을 학습시켜 뉴럴넷에 녹여내야한다. 오늘날 가장 실용적인 적용사례에서, 뉴럴넷 아키텍쳐들과 학습 시스템들은 **원자재(commodity)**로써 입지를 굳혀가고, 대부분의 액티브한 ‘소프트웨어 개발’은 라벨링되있는 데이터들을 선별하고 가공 정제하는데(curating, growing, massaging and cleaning) 집중되어 있다. 그리 고 이것은 우리의 소프트웨어에 반복해 적용하는 프로그래밍 패러다임을 본질적으로 전환시키고 있다. 개발 팀은 이에 따라 데이터셋을 수정하고 키우는 2.0 프로그래머들(데이터 라벨러들)과, 모델 학습코드 인프라, 분석, 시각화, 라벨링 인터페이스들을 감싸고 있는 코드들을 유지보수하고 반복하는 소수의 1.0 프로그래머들로 나뉜다.
파고들어보니, 대부분의 현실 문제들에서 직접 프로그램을 짜는 것보다 데이터를 수집하는 것(또는 더 일반적으로 말하자면, 목표하는 행동을 정의하는 것)이 더 쉬웠다. 데이터 수집이 직접 코딩보다 쉽다는 이유와 아래에서 설명할 소프트웨어 2.0 프로그램들의 장점들 때문에, 우리는 산업들이 1.0 코드에서 2.0 코드로 전환되는 것을 목격하고 있다. 소프트웨어 (1.0)은 세상을 먹어치웠고, 이제 AI(소프트웨어 2.0)은 소프트웨어를 먹어치우고 있다.
지금 일어나고 있는 전환(Ongoing Transition)
지금 일어나고 있는 전환들의 몇몇 예들을 간단하게 살펴보자. 각 예들은 직접 코드로 작성하기에는 너무 복잡해 포기하고 있다가 2.0으로 스택 전환이 되면서 근 몇 년 사이에 발전을 보인 분야들이다.
**Visual Recognition(시각 인식)**은 ****머신러닝(e.g. SVM)이 살짝 가미된(sprinkled on top at the end) 엔지니어된 피쳐들로 구성되어있었다. 그리고 우리는 큰 데이터셋(e.g. ImageNet과 같은)과 CNN 구조들의 스페이스 서칭을 통해 좀 더 강력한 visual feature들을 찾았다. 최근에는 해당 뉴럴넷 구조를 직접 서칭하지 않고, 서칭 자체를 뉴럴넷에 맡기게 되었다.
**Speech Recogntion(음성 인식)**은 ****수많은 전처리와 gaussian mixture 모델들과 hidden markov 모델들로 수행되었지만, 오늘날에는 완전히 뉴럴넷으로 수행된다. Fred Jelinek이 1985년에 쓴 인용에 따르면, ‘언어학자를 자를 때마다, 우리의 음성인식 시스템은 더 좋아질 것이다.’
Speech Synthesis(음성 합성)는 다양한 봉합 메커니즘(stitching mechanism)에 의해 시도되었으나, 오늘날에 최신 모델들은 오디오 시그널 아웃풋 그 자체를 생성하는 큰 ConvNet(e.g. WaveNet)들로 대체되었다.
**Machine Translation(기계번역)**은 어절 기반의 통계 기술들(phrase-based statistical techniques)로 시도되었었지만, 이것 또한 뉴럴넷으로 대체되었다. 필자가 좋아하는 구조는 weakly supervised 또는 아예 unsupervised한 환경에서 소스 언어에서 학습된 단일 모델이 다른 타겟 언어로 번역되는 다국어 셋팅이다.
Games. 룰 기반의 바둑 프로그램은 예전에 개발되었었지만, 어떤 프로그램도 AlphaGo Zero를 이기진 못한다. 필자는 DOTA2나 Starcraft 또한 그러리라 믿는다.
Databases. AI 밖의 전통적인 시스템들은 이미 서서히 전환을 겪고 있었다. ‘The Case for Learned Index Structures’는 기존의 cache-optimized B-Trees 알고리즘을 메모리에서는 10배가량(order-of-magnitude) 절약하고 속도 측면에서는 70% 이상 앞지르는 뉴럴넷으로 데이터 관리 시스템의 코어 부분을 대체하였다.