News Feed

파이썬 문법에 러스트 속도를 더하다…모조 입문 가이드

컨텐츠 정보

  • 조회 370

본문

모조 언어가 등장하면서 내세운 특징은 파이썬의 사용 편의성과 명확한 구문, 그리고 러스트의 속도와 메모리 안전성이라는 두 가지 세계의 장점을 모두 제공한다는 것이다.

한동안 이러한 주장을 검증하려면 온라인 노트북 환경을 사용해 원격 서버에서 모조 코드를 실행하는 방법밖에 없었다. 그러나 최근 모조 컴파일러가 맥과 리눅스용 독립형 다운로드 형태로 출시됐다. 마이크로소프트 윈도우는 아직 직접 지원되지는 않지만 WSL2를 통해 실행할 수 있다.

여기서는 로컬 환경에서 모조를 사용하면서 면면을 살펴보고 파이썬과의 유사점과 차이점, 그리고 파이썬을 비롯한 다른 언어에 익숙한 프로그래머에게 어떤 장점을 제공하는지에 대해 설명한다.

모조 언어에 대한 기본 지식

모조가 처음 발표됐을 당시 든 생각은 파이썬의 “상위 집합”이라는 것이다. 즉, 기존 파이썬 프로그램은 모조 프로그램으로서도 유효하다. 그러나 시간이 지나면서 모조의 목표는 파이썬과의 본질적 호환성을 제공하는 것이 아니라는 점이 분명해졌다. 모조의 목표는 기존 파이썬 프로그램을 실행하기 위한 런타임이 아니라, 파이썬 사용자에게 익숙한 구문을 제공하면서 예를 들어 러스트나 C++처럼 수동 메모리 관리가 가능한 저수준 프로그래밍에 더 적합한 기능을 갖추는 데 있다.

파이썬 프로그램 및 파이썬 생태계와의 완전한 호환성이 필요한 경우에는 파이썬 런타임을 호출해 대응할 수 있다. 다만 이 경우 성능 저하가 발생한다. 파이썬 런타임과 그 안에 있는 요소에 대한 호출에는 비용이 따르기 때문이다. 대처 방법은 파이썬 생태계가 필요한 상황에서는 파이썬을 사용하고, 성능이 우선인 상황에서는 모조를 사용하는 것이다.

모조가 파이썬 대비 가장 강조하는 장점은 LLVM 툴체인을 사용해 머신 네이티브 코드로 사전 컴파일된다는 점이다. 이는 속도 측면에서 모조 프로그램에 본질적인 우위를 제공한다. 성능상의 이 우위는 모조 전용 기능을 활용할 때 가장 명확하게 드러난다.

파이썬 기능을 위해서는 많은 경우 파이썬의 동적인 동작을 에뮬레이션해야 한다는 비용이 따르는데, 이러한 동작은 본질적으로 속도가 느리다. 모조에는 이를 일부 대체할 수 있는 네이티브 동작이 있다. 예를 들어 네이티브가 아니고 크기 제한도 없는 파이썬의 정수 대신 모조는 최대 256비트 정수를 지원하므로 SIMD 연산이 빠르다.

모조와 파이썬의 구문 비교

모조의 네이티브 언어 기능 중 상당수는 둘 중 하나에 해당한다. 하나는 파이썬에는 없는 완전히 새로운 기능, 다른 하나는 파이썬 기능의 고성능 버전이다. 후자의 경우 성능 향상을 얻는 대신 파이썬의 동적 특성을 잃게 된다.

예를 들어 파이썬에서는 변수 참조를 공식적으로 선언하는 방법이 없다. 변수는 그냥 필요할 때마다 생성된다. 모조에서는 var 키워드를 사용해 현재 스코프에서 명시적으로 변수를 선언할 수 있다. 변수 스코프를 다루는 방식도 다르다. 모조에서는 예를 들어 if 블록과 같은 주어진 중첩 코드 블록 내에서만 변수 스코프가 설정된다(단, 더 큰 스코프에서 변수를 사전 선언할 수 있음). 파이썬에서는 if 블록에 선언된 변수가 블록이 끝난 이후에도 유지된다.

또한 모조의 자체적인 struct 키워드는 파이썬의 class와 대비된다. 클래스는 말 그대로 파이썬 클래스로, 예상할 수 있는 모든 동적이고 느린 동작을 수반한다. 그러나 struct 타입은 C/C++, 러스트와 비슷해서 컴파일 시점에 결정된 레이아웃이 고정되지만 머신 네이티브 속도를 낼 수 있도록 최적화된다.

파이썬과 구분되는 모조의 또 다른 키워드는 fn이다. def 또는 fn을 사용해 함수를 정의할 수 있지만 fn은 명시적으로 정의된 경우에만 오류 발생을 허용한다. 일반적으로 fn 함수는 모든 자체 오류 조건을 내부적으로 처리한다. 즉, 불필요할 수도 있는 런타임 오류 처리 코드가 생성되지 않으므로 성능 측면에서 유리하다.

아래 코드는 점과 같은 엔티티를 위한 struct로, 위에 설명한 여러 원칙이 실제로 어떻게 적용되는지 보여준다.

struct Point:    var x: Int    var y: Int    fn __init__(out self, x: Int, y: Int)        self.x = x        self.y = y

파이썬 개발자라면 예를 들어 공백을 사용하는 부분 등에서 모조 코드가 파이썬과 매우 비슷하다는 사실을 바로 알아볼 수 있을 것이다. 그러나 둘 사이에는 여러 차이점이 있다.

모조 컴파일러와 툴체인

시스템에서 모조를 사용하려면 모듈러가 제공하는 바이너리를 다운로드해야 한다. 이미 파이썬 사용자라면 가장 쉽게 모조를 시작하는 방법은 파이썬 가상 환경을 설정해서 모조를 파이썬 패키지처럼 설치하는 것이다. 이렇게 하면 모조 프로젝트에 필요한 서드파티 파이썬 라이브러리를 이 venv에 설치해 사용할 수 있으므로 파이썬과의 교차 통합도 더 쉬워진다(이 부분에 대해서는 뒤에서 더 자세히 설명).

일단 설치만 하면 모조 프로그램 실행은 간단하다. 확장자가 .mojo인 파일을 만든 다음 mojo filename.mojo를 사용해 실행하기만 하면 된다. 모조 프로그램은 네이티브 코드로 컴파일되므로 시작 시간은 비슷한 파이썬 프로그램에 비해 현저히 길다. mojo build filename.mojo를 사용해서 독립형 바이너리로 컴파일하면 다시 컴파일하지 않고 재사용할 수 있다. 컴파일된 모조 바이너리는 아주 컴팩트하다. 리눅스에서 간단한 “Hello, World!” 프로그램을 컴파일할 경우 바이너리 크기는 19K에 불과하다.

모조 툴체인은 모듈러의 패키지 관리자 및 프로젝트 관리 툴인 pixi와 함께 사용할 수도 있다. pixi는 파이썬 프로젝트에 사용되는 모든 메타데이터(예를 들어 pyproject.toml)를 지원하므로 모조 전용 프로젝트뿐 아니라 모조와 파이썬을 혼합한 프로젝트도 관리할 수 있다. 또한 pixilockfile 및 환경 관리 메커니즘도 제공한다. 모조 리포지토리의 일부 데모 프로젝트는 pixi를 사용하지만, 이미 pip 또는 uv에 투자했다면 당연히 계속 사용해도 무방하다.

모조에서 파이썬 작업하기

모조 코드를 쓸 때 기본 전제는 입력하는 모든 요소가 모조라는 것이다. 따라서 파이썬 기능을 사용하고자 한다면 명시적으로 가져와야 한다. 예를 들어 파이썬의 넘파이(NumPy)를 사용하려면(예를 들어 기존 워크플로와 통합하기 위해) 다음과 같이 할 수 있다.

from python import Pythondef main():    np = Python.import_module("numpy")    rand_array = np.random.rand(32)

모조 모듈 python은 파이썬 생태계와의 상호운용성을 제공하며, Python.import_module 메서드는 파이썬의 자체 import 메커니즘처럼 작동한다. 파이썬의 모든 표준 라이브러리, 그리고 사용 중인 가상 환경에 설치된 모든 서드파티 모듈을 이 방식으로 가져올 수 있다. 다만 가져오기에는 제약이 있어서, 예를 들어 모조 모듈의 최상위 수준으로는 가져올 수 없으며 x import y와 같은 동작은 아직 에뮬레이션할 수 없다.

파이썬/모조 상호운용에서 중요한 부분은 모든 네이티브 파이썬 연산이 파이썬 런타임 인스턴스를 사용한다는 것이다. 즉, 모조 자체에서 에뮬레이션되지 않는다. 여기서 얻는 장점은 모든 파이썬 동작이 예상대로 이뤄진다는 점이고, 단점은 모조/파이썬 경계를 넘는 모든 호출에는 성능 비용이 따른다는 것이다. 이는 모조에 국한된 문제가 아니다. 파이썬의 외부 함수 인터페이스를 통해 이뤄지는 파이썬과 다른 언어 간의 모든 상호운용에는 호출 오버헤드가 발생한다. 일반적인 대처 방법은 연산을 일괄 처리함으로써 호출 횟수를 줄이는 것이다.

파이썬 프로그램을 모조와 동일한 환경에서 실행하는 경우에는 파이썬에서 모조를 호출할 수도 있다. 그러나 이를 위한 메커니즘은 복잡한 편이고 일부 성가신 작업도 필요하다. 그러나 결과적으로 파이썬은 모조 모듈을 C나 러스트로 작성된 확장 모듈이나 사이썬으로 만든 모듈처럼 인식하고 사용할 수 있게 된다.

모조가 파이썬을 대체할 수 있을까?

모조는 처음에는 데이터 과학과 머신러닝을 위한 언어를 지향했지만 시간이 지나면서 궤도를 수정했다. 설명서의 모조 소개 부분에서는 모조를 “고성능 AI 인프라와 이종 하드웨어에 맞게 설계된 시스템 프로그래밍 언어”라고 설명한다. 반면 파이썬은 본질적으로 시스템 언어는 아니지만 AI/ML 분야에서 “접착 언어”로 자리 잡으며 자체적으로는 불편한 이런저런 요소에 대한 편리한 인터페이스를 제공한다.

파이썬 대체는 단순히 더 빠른 언어를 만든다고 되는 일이 아니다. 애초에 실행 속도는 파이썬의 강점이 아니기 때문이다. 파이썬에서는 항상 실행 속도보다 개발 속도와 견고한 생태계가 우선이었다. 모조가 파이썬을 대체하려면 두 가지 범주 모두에서 단순히 경쟁하는 수준을 넘어 뛰어나야 한다. 기존 파이썬 라이브러리를 사용하는 데 그치지 않고(잠재적 성능 비용이 따르므로) 그러한 라이브러리에 대한 자체적인 네이티브 대안을 만들어야 한다. 웹 개발과 같은 분야에서 파이썬을 대체하려는 경우에도 마찬가지다. 이를 위해 필요한 모든 요소를 갖추기까지는 오랜 시간이 걸릴 것이다.

장기적으로 보면 다른 여러 언어와 마찬가지로 파이썬을 보완해서 파이썬으로는 여전히 하기 어려운 작업을 맡는 방식으로 사용되는 것이 최선일 수 있다. 그 과정에서 모조는 독자적으로 성장하면서 결국 나름의 틈새 영역을 찾게 될 것이다.
dl-itworldkorea@foundryco.com

관련자료

댓글 0
등록된 댓글이 없습니다.