나는 평생 연구에 종사했기 때문에 연구자들이 보기 흉한 코드를 작성한다는 고정관념을 알고 있습니다(예: 여기 , 여기 또는 여기 참조 ). 하지만 저는 우리가 고칠 수 있다고 생각했어요. 그렇죠? 그래서 저는 좋은 연구 프레임워크를 디자인하려고 여러 번 노력했습니다. 나는 내가 즐겨 읽는 소프트웨어 엔지니어링 서적과 블로그를 사용하여 인터페이스를 가져오고 멋진 추상화를 만들려고 노력했습니다.
그러나 그 모든 노력은 번번이 수포로 돌아갔습니다. 제가 작업한 대부분의 연구 소프트웨어는 프로덕션으로 전환되지 않았습니다(일부는 그랬지만). 누군가 나에게 간단한 진실을 말해주었다면 내 정신 건강에 좋았을 것입니다. 죽어가는 연구 코드는 실제로 일어나야 하는 일입니다 . 연구자들은 애초에 그것을 엔지니어링하는 데 많은 시간을 소비해서는 안 됩니다.
전문 소프트웨어 엔지니어는 항상 최고의 소프트웨어 방법을 사용하지 않는 연구원을 무시합니다. 연구 코드의 기준을 높이려는 게시물이 여러 개 있습니다(예: 이 훌륭한 게시물 과 연구 코드 핸드북 ). 하지만 이 게시물은 다른 방향으로 진행됩니다. 최고의 소프트웨어 관행을 과도하게 사용하지 않고 대신 빠른 탐색에만 투자하는 방법을 논의합니다. 많은 아이디어를 빠르게 시도하는 것이 목표인 연구 중심 회사를 대상으로 합니다.
회사의 성공적인 연구 프로젝트는 탐색과 활용이라는 두 단계로 구성됩니다. "탐색"에서는 가능한 한 많은 다양한 솔루션을 시도하고 싶습니다. "활용" 중에는 최상의 솔루션을 강화하고 이를 유용한 제품으로 바꿔야 합니다.
최적의 소프트웨어 관행은 둘 사이에 상당히 다릅니다. 그렇기 때문에 기업에서는 연구 부서와 제품 부서를 별도로 두는 경우가 많습니다. 소프트웨어 설계에 관해 일반적으로 읽을 수 있는 모든 책은 주로 두 번째 "이용" 단계에 관한 것입니다. 이 단계에서는 확장 가능한 제품을 위한 기반을 구축합니다. 여기에서 멋진 API, 로깅, 오류 처리 등 모든 디자인 패턴이 필요합니다.
그러나 첫 번째 "탐사" 단계에서는 영원히 지속될 기반을 구축하는 것이 아닙니다 . 실제로, 대부분의 노력이 살아남는다면 (정의에 따라) 충분한 탐색을 하지 않은 것입니다.
이 게시물의 많은 관행은 일반적으로 "기술 부채"가 되는 사례입니다. 깨끗하고 재사용이 가능하고 잘 추상화된 코드를 작성하지 않음으로써 얻을 수 있는 것입니다. 빚은 항상 나쁜 것인가? 우리는 대출이나 주택담보대출을 받지 않는 것을 선호하지만, 돈을 빌리는 것은 종종 인생에서 좋은 전략이 됩니다. 빨리 움직이고 나중에 이익을 얻으려면 빚을 지는 것이 좋습니다.
마찬가지로 기술 부채를 지지 않으면 연구 속도가 느려질 수 있습니다. 좋은 소식은 대부분의 경우 돈을 갚을 필요가 없다는 것입니다. 어쨌든 대부분의 연구 코드는 죽을 가능성이 높습니다. 따라서 평균적으로 귀하는 귀하가 짊어진 전체 기술 부채로 고통받지 않을 것입니다.
많은 소프트웨어 아키텍처와 리팩토링 기술은 특히 코드 재사용성을 향상시키는 데 중점을 두고 있습니다. 코드 재사용에는 일반적인 단점이 있습니다. 그러나 프로덕션에서는 잘 알려진 이점보다 더 중요합니다(예를 들어 이 일반적인 게시물 참조). 연구 프로젝트에서 대부분의 코드는 망각될 운명입니다. 코드 재사용을 위해 노력하면 실제로 속도가 느려질 수 있습니다.
코드 재사용을 제한하는 것은 연구에 사용해도 괜찮은 기술적 부채 유형입니다. 제가 논의하고 싶은 코드 재사용 패턴에는 불필요한 종속성 추가, 코드 복사 붙여넣기, 많은 공유 연구 코드 유지, 조기 설계 투자 등이 있습니다.
속도를 높여줄 잘 관리되고 버전화된 라이브러리를 알고 있다면 그것을 선택하십시오! 그러나 새로운 종속성을 도입하기 전에 그만한 가치가 있는지 판단해 보십시오. 추가될 때마다 의존성 지옥에 더 가까워집니다. 학습하고 문제를 해결하는 데 시간을 투자하게 됩니다. 이 간결한 게시물 에서 종속성의 더 많은 함정을 확인하세요.
다음과 같은 경우 무언가에 의존하는 것이 좋습니다.
그러나 다음과 같은 경우 종속성에 주의하세요.
빨리 사용하는 방법을 알 수 없거나, 아주 새로운 것(또는 아주 오래된 것)이거나, 아무도 모르는 것 같습니다. 문서나 테스트가 없습니다.
그것은 귀하의 모노레포에서 왔으며 다른 팀에 의해 지속적으로 변경되고 있습니다.
다른 많은 종속성과 도구를 가져옵니다. 아니면 설치가 어렵나요?
그리고 마지막으로 당신(또는 일부 LLM)이 몇 시간 안에 이 코드를 작성할 수 있다고 생각합니다.
명시적인 종속성 대신에 다음 주제인 “ 약간 복사하는 것이 약간의 종속성보다 낫습니다 ”라는 멋진 Go 속담을 따를 수 있습니다.
어떤 사람들은 “ 복사 붙여넣기가 불법이어야 한다 ”고 말합니다. 그러나 놀랍게도 나는 그것을 꽤 자주 찬성하는 입장을 보였습니다. Copypaste는 탐색 단계에서 최적의 선택이 될 수 있습니다.
코드베이스의 다른 부분에서 많이 사용되는 함수에 의존하는 경우 쉽게 변경하는 것을 잊어버릴 수 있습니다. 누군가를 위해 무언가를 망칠 가능성이 높으며 코드 검토 및 수정에 귀중한 시간을 소비해야 합니다. 그러나 필요한 코드를 폴더에 복사하여 붙여넣으면 원하는 모든 작업을 자유롭게 수행할 수 있습니다. 이는 실험이 예외가 아닌 표준이 되는 연구 프로젝트에서 큰 문제입니다. 특히 변경 사항이 모든 사람에게 유용할지 확실하지 않은 경우에는 더욱 그렇습니다.
복사 붙여넣기에는 딥러닝 코드베이스가 가장 적합하다고 생각합니다. 일반적으로 모델과 해당 교육을 설명하는 데 필요한 코드의 양은 그리 크지 않습니다. 그러나 동시에 그것은 매우 미묘하고 일반화하기 어려울 수 있습니다. 공유 가능한 훈련 스크립트는 관리하기 어려운 크기로 커지는 경향이 있습니다. 예를 들어 Hugging Face transformers
Trainer에는 4,000개 이상의 라인이 있습니다. 흥미롭게도 트랜스포머는 모델 수준에서 복사 붙여넣기를 선택했습니다. "단일 파일 모델" 정책에 대한 이유가 담긴 게시물을 확인해 보세요. 끝 부분에서 복사 붙여넣기의 아름다움에 대한 더 많은 리소스를 확인하세요.
복사 붙여넣기의 대안은 지점에 머무르는 것입니다. 하지만 팀워크에 너무 많은 오버헤드가 발생하는 것 같습니다. 또한, 복사 붙여넣기의 아름다움에 관한 여러 게시물을 더 찾았습니다. 결론에서 더 많은 게시물을 확인하세요.
많이 사용되는 공유 코드를 유지 관리하려면 많은 작업이 필요합니다. Pytorch
버전에 대해 표시된 torch.nn.Module
파일 행 수를 살펴보세요. 가장 발전된 연구 팀조차도 복잡성을 제어하는 데 어려움을 겪고 있음을 알 수 있습니다.
대규모 공유 연구 코드를 유지하는 데 필요한 시간과 리소스를 과소평가하지 마십시오. 연구 라이브러리를 많이 사용할수록 더 복잡해집니다. 모든 연구 방향은 사용 사례가 약간 다르기 때문에 일반적인 도서관보다 빠르게 발생합니다. 무엇을 다시 기부할 수 있는지에 대해 매우 엄격한 규칙을 설정하세요. 그렇지 않으면 공유 코드가 취약해지고 수많은 옵션, 버그가 있는 최적화 및 엣지케이스로 인해 무성해집니다. 대부분의 연구 코드가 소멸되므로 이 모든 추가 복잡성은 다시는 사용되지 않습니다. 공유 코드 중 일부를 삭제하면 실제 연구를 수행할 시간이 확보됩니다.
프로덕션 환경에서도 코드의 미래 보장을 너무 많이 원하지 않는다는 것은 어느 정도 사실입니다. 요구 사항을 충족하는 가장 간단한 솔루션을 구현해 보십시오. 그러나 프로덕션 코드에는 항상 고려해야 할 유지 관리 측면이 있습니다. 예를 들어 오류 처리, 속도, 로깅, 모듈화는 일반적으로 고려해야 할 사항입니다.
연구 코드에서는 그 어느 것도 중요하지 않습니다. 당신은 가능한 가장 빠른 방법으로 아이디어가 좋은지 나쁜지 빠르게 증명하고 계속 진행하기를 원할 뿐입니다. 따라서 모듈이나 API 없이 이를 달성하는 지저분한 단순성은 완전히 괜찮습니다!
다음과 같은 조기 소프트웨어 투자에 귀중한 시간을 낭비하지 마십시오.
연구 프로젝트의 목표는 새로운 해결책을 찾는 것입니다. (정의상) 그것이 어떻게 생겼는지 아는 사람은 아무도 없습니다. 이는 정보가 제한된 복잡한 연구 환경에서의 최적화 프로세스와 유사합니다. 좋은 최소값을 찾으려면 많은 경로를 시도하고 좋은 경로와 나쁜 경로를 인식하고 로컬 최소값에 갇히지 않아야 합니다. 이 모든 것을 빠르게 수행하려면 때로는 기술 부채를 지는 대신 소프트웨어에 투자해야 합니다.
시도해보고 싶은 다양한 연구 경로가 있습니다. 대부분의 경로에서 시간을 단축할 수 있는 디자인, 라이브러리 또는 최적화가 있습니까? 시도하려는 아이디어를 항상 모두 알 수는 없기 때문에 지나치게 엔지니어링하지 않도록 주의해야 합니다. 이는 모든 프로젝트에 매우 맞춤화되어 있지만 다음은 몇 가지 예입니다.
연구자들은 새롭고 다양한 아이디어를 신속하게 시작할 수 있어야 합니다. 프로젝트 초반에는 쉬운 것 같습니다. 그러나 사람들이 자신이 좋아하는 연구 경로에 확고히 자리잡게 되면서 점차적으로 그것은 점점 더 어려워졌습니다. 이를 해결하려면 문화적, 조직적 변화가 필수적이다. 너무 많은 돈과 감정을 투자하기 전에 전망이 좋지 않은 연구를 중단하는 과정이 있어야 합니다. 정기적인 데모 데이와 동료 기술 검토는 이러한 목적을 위한 효과적인 전략이 될 수 있습니다. 사람들이 새롭고 빛나는 아이디어에 뛰어드는 것과 현재 프로젝트를 적절하게 마무리하는 것 사이의 균형을 찾는 것도 중요합니다.
그러나 이것은 소프트웨어 게시물이므로 새 프로젝트를 쉽게 확장할 수 있는 몇 가지 방법은 다음과 같습니다.
시끄럽고 버그가 많은 코드로 인해 결과가 너무 모호하고 결정적이지 않아 전체 프로젝트가 시간 낭비가 됩니다. 지나치게 엔지니어링해서는 안 되지만 다음과 같은 간단한 경험 법칙을 따르면 지저분한 코드를 쉽게 피할 수 있습니다.
부작용이 있는 코드 피하기
클래스보다는 함수가 기본값입니다. 클래스에서는 캡슐화와 상속을 선호합니다.
함수/클래스/모듈의 길이를 최소화합니다. if 문 수 최소화
Python을 잘 알지만 간단한 기술을 사용하십시오. 메타클래스, 데코레이터 및 함수형 프로그래밍의 지적 잡초에 빠지는 유혹에 저항하십시오.
서로 다른 실행 중에 서로 다른 결과를 생성하는 소프트웨어는 작업하기 까다롭습니다. 불운한 씨앗을 바탕으로 중요하지만 잘못된 결정을 내렸다면 회복하는 데 많은 시간을 낭비하게 될 것입니다. 비결정적 소프트웨어를 다룰 때의 몇 가지 팁은 다음과 같습니다.
핵심은 연구 코드에 대한 이 게시물 에서 나왔습니다.
“코드가 핵심이 아니기 때문에 [좋은 소프트웨어 설계]에 신경 쓰지 않아도 됩니다. 코드는 필요한 답을 얻는 도구입니다.”
훌륭한 코딩 기초를 갖추는 것은 매우 중요합니다. 하지만 결국에는 탐구와 실제로 유용한 제품이 중요합니다. 연구에 프로덕션 소프트웨어를 너무 많이 사용하면 새로운 것을 발견하는 데 필요한 시간을 낭비하게 됩니다. 대신, 탐색 과정을 느리게 만드는 것이 무엇인지 찾아보세요. 빠른 분기, 결과 도출 시간, 잡음 없는 코드 정리에 투자하여 연구 경로의 속도를 높이세요.
코드 재사용에 대해 완전히 반대하는 것은 미친 짓입니다. 코드 재사용은 균형 잡힌 활동이어야 한다는 점을 지적하고 싶습니다. 연구에서는 프로덕션에서보다 폐기되는 코드의 비율이 더 큽니다. 저울은 재사용에 대해 더욱 기울어졌습니다. 다음은 코드 재사용의 함정이 있는 몇 가지 훌륭한 게시물입니다.
다음은 복사 붙여넣기 관행을 주장하는 몇 가지 게시물입니다.
읽어 주셔서 감사합니다! 약간 논란의 여지가 있는 부분도 있는 것 같으니 댓글로 알려주세요!
여기에도 나타납니다.