새로운 120B급 모델에 대해 기대감을 가지고, 제가 해결하는 데 며칠이 걸렸던 문제로 테스트해 보기로 했습니다. 문제는 데이터를 한 표현 방식에서 다른 방식으로 재배열하되, 동적 할당 (dynamic allocations) 없이 고정된 메모리 예산 내에서 수행하는 것입니다. 후자의 조건 때문에 솔루션을 단계별로 분해하기가 어려운데, 초기 단계에서 데이터를 잘못 저장하면 나중에 여유 공간이 남지 않기 때문입니다. 로컬 Qwen 모델들 (3.5-122B-A10B UD-IQ4_XS 및 3.6-27B UD-Q4_K_XL)은 이 문제에서 실패했습니다. Laguna는 코드를 작성하기 전까지 6만 개 이상의 사고 토큰 (thinking tokens)을 생성했지만, 결국 테스트를 통과하는 코드를 작성해 냈습니다. 비록 두 개의 작은 정수를 하나의 64비트 값으로 패킹 (packing)하는 방식의 약간의 편법 (dirty hack)을 사용하긴 했지만 말입니다 (잠재적으로, 하지만 가능성은 낮게, 둘 다 32비트보다 클 수 있으며, 이 경우 알고리즘은 실패합니다). 다른 게시물에서도 언급되었듯이, 이러한 긴 사고 과정은 일반적인 코딩 작업에는 부적합할 수 있지만, 어려운 문제의 디버깅 (debugging)과 검토 (review)를 위해서는 이렇게 작은 크기에서 철저하게 사고하는 모델을 갖는 것이 좋습니다. 테스트는 rope-scaling = yarn, rope-scale = 32, yarn-orig-ctx = 8192, yarn-attn-factor = 1.0 설정으로 수행되었습니다. 문제 자체는 다음과 같습니다: 원본 데이터인 id는 Union-Find 데이터 구조의 클러스터 루트 노드들을 나타내는 정수 배열이며, 총 클러스터 수 Nc입니다. 클러스터의 루트 노드는 해당 클러스터에 속한 요소 중 가장 작은 인덱스입니다. 최악의 시나리오에서 클러스터의 수는 id의 아이템 수와 거의 비슷합니다 (일반적인 상황은 하나 또는 두 개의 큰 클러스터가 있고 나머지는 연결되지 않은 요소들이어서 Nc = O(N)인 경우입니다). 저는 이를 다음과 같은 구조를 가진 배열 리스트 (array list)로 변환해야 합니다:
- list[1] : Nc, 클러스터 수
- list[2:Nc+1] : 리스트 내 클러스터들의 시작 인덱스
- list[Nc+2] : length(list) + 1, Nc+1 번째 클러스터의 센티넬 (sentinel) "시작 인덱스"
- list[list[2]:list[3]-1] : 첫 번째 클러스터에 속하는 id 요소들의 인덱스
- ...
등 리스트의 끝까지의 id는 클러스터 ID가 1부터 Nc 범위 내에서 할당되도록 수정되어야 합니다. 클러스터는 크기에 따라 내림차순으로 정렬되어야 합니다. 클러스터 내부에서 인덱스들은 오름차순으로 정렬됩니다. 만약 여러 클러스터의 크기가 같다면, id 내에서 루트 요소(root elements)가 나타나는 순서대로 정렬되어야 합니다. 예시: id = [1, 2, 2, 1, 5, 2, 5, 5, 5], Nc = 3 인 경우, id = [3, 2, 2, 3, 1, 2, 1, 1, 1], list = [3, 6, 10, 13, 15, 5, 7, 8, 9, 2, 3, 6, 1, 4]로 변환되어야 합니다. 이 알고리즘은 Julia 언어로 구현되어야 하며, list를 생성하는 것 외에는 메모리 할당(memory allocation) 없이 작동해야 합니다. /u/pand5461 제출 [link] [comments]