```html Autorzy: Mayank Mishra⋆, IBM Matt Stallone⋆, IBM Gaoyuan Zhang⋆, IBM Yikang Shen, IBM Aditya Prasad, IBM Adriana Meza Soria, IBM Michele Merler, IBM Parameswaran Selvam, IBM Saptha Surendran, IBM Shivdeep Singh, IBM Manish Sethi, IBM Xuan-Hong Dang, IBM Pengyuan Li, IBM Kun-Lung Wu, IBM Syed Zawad, IBM Andrew Coleman, IBM Matthew White, IBM Mark Lewis, IBM Raju Pavuluri, IBM Yan Koyfman, IBM Boris Lublinsky, IBM Maximilien de Bayser, IBM Ibrahim Abdelaziz, IBM Kinjal Basu, IBM Mayank Agarwal, IBM Yi Zhou, IBM Chris Johnson, IBM Aanchal Goyal, IBM Hima Patel, IBM Yousaf Shah, IBM Petros Zerfos, IBM Heiko Ludwig, IBM Asim Munawar, IBM Maxwell Crouse, IBM Pavan Kapanipathi, IBM Shweta Salaria, IBM Bob Calio, IBM Sophia Wen, IBM Seetharami Seelam, IBM Brian Belgodere, IBM Carlos Fonseca, IBM Amith Singhee, IBM Nirmit Desai, IBM David D. Cox, IBM Ruchir Puri†, IBM Rameswar Panda†, IBM Abstrakt Duże modele językowe (LLM) trenowane na kodzie rewolucjonizują proces tworzenia oprogramowania. Coraz częściej LLM do kodu są integrowane ze środowiskami programistycznymi w celu poprawy produktywności ludzkich programistów, a agenci oparty na LLM zaczynają wykazywać obiecujące wyniki w samodzielnym radzeniu sobie ze złożonymi zadaniami. Realizacja pełnego potencjału LLM do kodu wymaga szerokiego zakresu możliwości, w tym generowania kodu, naprawy błędów, wyjaśniania i dokumentowania kodu, utrzymywania repozytoriów i wielu innych. W niniejszej pracy przedstawiamy serię modeli kodowych z rodziny Granite, opartych na architekturze dekodera, trenowanych na kodzie napisanym w 116 językach programowania. Rodzina modeli Granite Code składa się z modeli o rozmiarach od 3 do 34 miliardów parametrów, odpowiednich do zastosowań od złożonych zadań modernizacji aplikacji po przypadki użycia wymagające ograniczonej pamięci na urządzeniu. Ewaluacja na obszernym zestawie zadań pokazuje, że modele Granite Code konsekwentnie osiągają wyniki na poziomie state-of-the-art wśród dostępnych otwartych kodowych LLM. Rodzina modeli Granite Code została zoptymalizowana pod kątem przepływów pracy w korporacyjnym tworzeniu oprogramowania i dobrze sprawdza się w szerokim zakresie zadań kodowania (np. generowanie kodu, naprawa i wyjaśnianie), co czyni ją wszechstronnym „wszystkomającym” modelem kodu. Udostępniamy wszystkie nasze modele Granite Code na licencji Apache 2.0 zarówno do celów badawczych, jak i komercyjnych. https://github.com/ibm-granite/granite-code-models 1 Wprowadzenie W ciągu ostatnich kilku dekad oprogramowanie stało się integralną częścią każdego aspektu naszego społeczeństwa. Wraz z rosnącym zapotrzebowaniem na tworzenie oprogramowania, kluczowe stało się zwiększenie produktywności programistów, a LLM stanowią obiecującą drogę do wsparcia ludzkich programistów. Główne zastosowania LLM w zwiększaniu produktywności tworzenia oprogramowania obejmują generowanie kodu, wyjaśnianie kodu, naprawianie kodu, generowanie testów jednostkowych i dokumentacji, modernizację aplikacji, wykrywanie luk, tłumaczenie kodu i wiele innych. W ostatnich latach nastąpił szybki postęp w zdolności LLM do generowania i manipulowania kodem, a dziś dostępna jest szeroka gama modeli o imponujących zdolnościach kodowania. Modele mają rozmiary od pojedynczych miliardów parametrów (np. Llama-7B (Touvron et al., 2023), Gemma-7B (Gemma-Team et al., 2024) itp.) do setek miliardów: DBRX (Databricks), Arctic (Snowflake), Grok, Mixtral 8x22B (MistralAI), Command R+ (Cohere) i różnią się ogólnością zamierzonego zastosowania, przy czym niektóre modele mają na celu obejmowanie szerokiego zakresu zastosowań poza kodowaniem, podczas gdy inne koncentrują się głównie na zadaniach związanych z kodowaniem (np. StarCoder (Li et al., 2023a; Lozhkov et al., 2024), CodeGen (Nijkamp et al., 2023), CodeLlama (Rozie`re et al., 2023), CodeGemma (CodeGemma Team et al., 2024)). Jednak w obecnym polu LLM do kodu, zwłaszcza w kontekście korporacyjnego tworzenia oprogramowania, nadal istnieją ważne luki. Po pierwsze, chociaż bardzo duże, ogólne LLM mogą osiągać doskonałe wyniki w kodowaniu, ich rozmiar sprawia, że są drogie we wdrożeniu. Mniejsze modele skupione na kodowaniu ( , ; , ; , ; , ; , ) mogą osiągać doskonałe wyniki w generowaniu kodu w mniejszym i bardziej elastycznym opakowaniu, ale wydajność w zadaniach kodowania poza generowaniem (np. naprawa i wyjaśnianie) może być gorsza od wydajności generowania kodu. Li et al. 2023a Lozhkov et al. 2024 Nijkamp et al. 2023 Rozie`re et al. 2023 CodeGemma Team et al. 2024 W wielu kontekstach korporacyjnych adopcja LLM do kodu może być dodatkowo skomplikowana przez czynniki wykraczające poza wydajność modeli. Na przykład, nawet otwarte modele czasami cierpią na brak przejrzystości co do źródeł danych i metod przetwarzania danych użytych do stworzenia modelu, co może podważać zaufanie do modeli w kontekstach o kluczowym znaczeniu i regulowanych. Ponadto, warunki licencyjne w dzisiejszych otwartych LLM mogą utrudniać i komplikować możliwość korzystania z modelu przez przedsiębiorstwo. Prezentujemy modele Granite Code, serię bardzo wydajnych kodowych LLM, zaprojektowanych do wspierania korporacyjnego tworzenia oprogramowania w szerokim zakresie zadań kodowania. Modele Granite Code mają dwa główne warianty, które udostępniamy w czterech różnych rozmiarach (3B, 8B, 20B i 34B): podstawowe modele bazowe do zadań związanych z kodem; Granite Code Base: modele postępujące zgodnie z instrukcjami, dostrojone przy użyciu kombinacji commitów Git połączonych z ludzkimi instrukcjami oraz otwartych, syntetycznie wygenerowanych zbiorów danych instrukcji kodu. Granite Code Instruct: Modele bazowe z serii zostały wytrenowane od podstaw przy użyciu dwufazowej strategii treningowej. W fazie 1 nasz model jest trenowany na 3 do 4 bilionach tokenów pochodzących z 116 języków programowania, co zapewnia kompleksowe zrozumienie języków programowania i składni. W fazie 2 nasz model jest dalej trenowany na 500 miliardach tokenów z starannie zaprojektowaną mieszanką wysokiej jakości danych z domen kodu i języka naturalnego, aby poprawić zdolność modelu do rozumowania. Używamy celu modelowania językowego bez nadzoru do trenowania modeli bazowych w obu fazach treningu. Modele instruktażowe są pochodne od dalszego dostrajania wyżej wymienionych wytrenowanych modeli bazowych na kombinacji przefiltrowanego wariantu CommitPack ( , ), zbiorów danych instrukcji języka naturalnego (OASST ( , ), HelpSteer ( , )) oraz otwartych zbiorów danych matematycznych (MathInstruct ( , ) i MetaMathQA ( , )), w tym syntetycznie wygenerowanych zbiorów danych kodu w celu poprawy zdolności do postępowania zgodnie z instrukcjami i rozumowania. Muennighoff et al. 2023 Ko¨ pf et al. 2023 Wang et al. 2023 Yue et al. 2023 Yu et al. 2023 Przeprowadzamy obszerne ewaluacje naszych kodowych LLM na obszernym zestawie benchmarków, w tym HumanEvalPack ( , ), MBPP(+) ( , ; , ), RepoBench ( , ), ReCode ( , ) i więcej. Ten zestaw benchmarków obejmuje wiele różnych rodzajów zadań kodowania poza syntezą kodu w Pythonie, np. naprawa kodu, wyjaśnianie kodu, edycja kodu, tłumaczenie kodu itp., w większości głównych języków programowania (Python, JavaScript, Java, Go, C++, Rust itp.). Muennighoff et al. 2023 Austin et al. 2021 Liu et al. 2023a Liu et al. 2023b Wang et al. 2022 Nasze wyniki pokazują, że wśród modeli open-source, modele Granite Code ogólnie wykazują bardzo silną wydajność we wszystkich rozmiarach modeli i benchmarkach (często przewyższając inne otwarte modele kodu, które są dwukrotnie większe od Granite). Dla ilustracji, rysunek (na górze) pokazuje porównanie Granite-8B-Code-Base z innymi otwartymi bazowymi kodowymi LLM, w tym z niedawno wydanymi, wysokowydajnymi ogólnymi bazowymi LLM, takimi jak Mistral ( , ) i LLama-3 ( , ) na HumanEvalPack ( , ). Chociaż CodeGemma i StarCoder2 osiągają przyzwoite wyniki w generowaniu kodu, znacznie gorzej wypadają w wariantach HumanEvalPack dotyczących naprawy i wyjaśniania kodu. Średnio, Granite-8B-Code-Base przewyższa najbardziej konkurencyjny model CodeGemma-8B o prawie 12 punktów na HumanEvalPack (33,2% vs 21,3%), mimo że jest trenowany na znacznie mniejszej liczbie tokenów (4,5T vs 7,5T tokenów). Oprócz modeli bazowych, dostrojone instruktażowo warianty naszych modeli Granite Code również wykazują silną wydajność na HumanEvalPack, przewyższając inne otwarte (kodowe) modele instruktażowe, co pokazuje korzyści dla szerszego zestawu zadań kodowania z instrukcjami w języku naturalnym (patrz rysunek (na dole)). 1 Jiang et al. 2023b AI@Meta 2024 Muennighoff et al. 2023 1 Ponadto, ponieważ rozumowanie jest kluczowe dla rozwiązywania złożonych pytań i zadań, testujemy również nasz model Granite-8B-Code-Base na sześciu benchmarkach matematycznych, w tym MATH ( , ), GSM8K ( , ) i rozwiązywanie problemów z dostępem do narzędzi obliczeniowych, gdzie nasz model Granite 8B osiąga lepsze wyniki w porównaniu z większością najnowocześniejszych LLM o rozmiarze 7B lub 8B. Na przykład, Granite-8B-Code-Base przewyższa Llama-3-8B-Base o ~12 punktów na GSM8K i ~6 punktów na MATH (patrz tabela ). Cobbe et al. 2021 Cobbe et al. 2021 15 Kluczowe zalety modeli Granite Code obejmują: : Modele Granite Code osiągają konkurencyjną lub najlepszą wydajność w różnych rodzajach zadań związanych z kodem, w tym generowanie kodu, wyjaśnianie, naprawa, edycja, tłumaczenie itp., demonstrując ich zdolność do rozwiązywania różnorodnych zadań kodowania; Wszechstronny kodowy LLM : Wszystkie nasze modele są trenowane na danych dopuszczonych do obrotu, zebranych zgodnie z zasadami etyki AI IBM i kierowane przez zespół prawny IBM w celu zapewnienia godnego zaufania użytkowania w przedsiębiorstwie. Wszystkie modele Granite Code są udostępniane na licencji Apache 2.0. Godny zaufania LLM klasy korporacyjnej 1 Cały nasz potok zbierania, filtrowania i przetwarzania danych opisujemy w sekcji . Sekcja opisuje szczegóły architektury modelu, a sekcja zawiera szczegóły dotyczące trenowania. Sekcja zawiera szczegóły dotyczące dostrajania instruktażowego, a sekcja opisuje eksperymenty i wyniki porównujące modele Granite Code z innymi otwartymi LLM. 2 3 4 5 6 2 Zbieranie danych W tej sekcji opisujemy proces pobierania i filtrowania (Sekcja ), deduplikacji (Sekcja ), filtrowania HAP/PII (Sekcja ) używany do przygotowania danych kodu do trenowania modelu. Udostępniamy również przegląd wysokiej jakości danych języka naturalnego użytych do poprawy zrozumienia języka przez model i umiejętności rozumowania matematycznego. 2.1 2.2 2.3 2.1 Pobieranie i filtrowanie danych Dane kodu do pre-treningu pochodziły z kombinacji publicznie dostępnych zbiorów danych, takich jak Github Code Clean , StarCoderdata , oraz dodatkowych publicznych repozytoriów kodu i wydań z GitHub. Filtrujemy surowe dane, aby zachować listę 116 języków programowania z ponad 300 języków, jak wymieniono w Załączniku . Przypisanie danych do języków programowania odbywa się wyłącznie na podstawie rozszerzenia pliku, podobnie jak w StarCoder ( , ). Po filtrowaniu języków stosujemy cztery kluczowe reguły filtrowania w celu odrzucenia kodu niższej jakości ( , ): (1) usuwamy pliki z mniej niż 25% znaków alfabetycznych, (2) z wyjątkiem języka XSLT, odrzucamy pliki, w których ciąg znaków „<?xml version=” pojawia się w pierwszych 100 znakach, (3) dla plików HTML zachowujemy tylko te pliki, w których widoczny tekst stanowi co najmniej 20% kodu HTML i ma minimalną długość 100 znaków, (4) dla plików JSON i YAML zachowujemy tylko te pliki, które mają liczbę znaków w zakresie od 50 do 5000. Filtrujemy również wydania GitHub przy użyciu zestawu metryk jakości, które obejmują usuwanie tekstu generowanego automatycznie, filtrowanie wydań nieanglojęzycznych, wykluczanie komentarzy botów i wykorzystanie liczby zaangażowanych użytkowników w rozmowie jako wskaźnika jakości. Każdy plik kodu opatrujemy również informacją o licencji związaną z odpowiednim repozytorium, uzyskaną za pomocą interfejsów API GitHub i zachowujemy tylko pliki z licencjami permisywnymi do trenowania modeli. 2 3 A Li et al. 2023a Li et al. 2023a 2.2 Dokładna i przybliżona deduplikacja Stosujemy agresywną strategię deduplikacji, obejmującą zarówno dokładną, jak i przybliżoną deduplikację, aby usunąć z naszego zbioru treningowego dokumenty o (niemal) identycznej zawartości kodu. W przypadku dokładnej deduplikacji najpierw obliczamy hasze SHA256 na zawartości dokumentu i usuwamy rekordy o identycznych haszach. Po dokładnej deduplikacji stosujemy przybliżoną deduplikację, której celem jest usunięcie plików kodu, które mogą mieć niewielkie wariacje, a tym samym dalsze obniżenie obciążenia danych. Stosujemy do tego dwuetapową metodę: (1) obliczamy MinHashe wszystkich dokumentów, a następnie wykorzystujemy Locally Sensitive Hashing (LSH) do grupowania dokumentów na podstawie ich MinHash fingerprintów, (2) mierzymy podobieństwo Jaccarda między każdą parą dokumentów w tym samym wiadrze i oznaczamy dokumenty, z wyjątkiem jednego, jako duplikaty na podstawie progu podobieństwa 0,7. Proces ten stosujemy do wszystkich języków programowania, w tym do wydań GitHub, w celu zwiększenia bogactwa i różnorodności zbioru treningowego. 2.3 Filtrowanie HAP, PII, Malware Aby zmniejszyć prawdopodobieństwo generowania przez modele języka nienawistnego, obraźliwego lub wulgarnego (HAP), dokładamy wszelkich starań, aby filtrować treści HAP ze zbioru treningowego. Najpierw tworzymy słownik słów kluczowych HAP, a następnie opatrujemy każdy dokument kodu liczbą wystąpień takich słów kluczowych w jego zawartości, w tym w komentarzach. Odrzucamy dokumenty, które przekraczają próg HAP, obliczony na podstawie analizy dystrybucyjnej, a także manualnej inspekcji plików kodu. Ponadto, w celu ochrony prywatności, postępujemy zgodnie ze StarCoder ( , ) i dokładamy wszelkich starań, aby zredagować dane osobowe (PII) ze zbioru treningowego. W szczególności wykorzystujemy model StarPII do wykrywania adresów IP, kluczy, adresów e-mail, nazwisk, nazw użytkowników i haseł znalezionych w treści. Krok redakcji PII zastępuje tekst PII odpowiednimi tokenami NAME , EMAIL , KEY , PASSWORD i zmienia adres IP na syntetycznie wygenerowany adres IP, jak w Li et al. (2023a). Skanujemy również nasze zbiory danych za pomocą narzędzi do identyfikacji i usuwania złośliwego oprogramowania w kodzie źródłowym. Li et al. 2023a 4 2.4 Zbiory danych w języku naturalnym Oprócz zbierania danych kodu do trenowania modelu, przygotowujemy kilka publicznie dostępnych, wysokiej jakości zbiorów danych w języku naturalnym w celu poprawy biegłości modelu w rozumieniu języka i rozumowaniu matematycznym. Reprezentatywne zbiory danych z tej kategorii obejmują dokumenty internetowe (Stackexchange, CommonCrawl), teksty matematyczne z internetu (OpenWeb-Math; ( ), StackMathQA; ( )), teksty akademickie (Arxiv, Wikipedia) oraz zbiory danych do dostrajania instruktażowego (FLAN; ( ), HelpSteer ( , )). Nie deduplikujemy tych już przetworzonych zbiorów danych w języku naturalnym. Paster et al. 2023 Zhang 2024 Longpre et al. 2023 Wang et al. 2023 3 Architektura modelu Trenujemy serię modeli kodu o różnej wielkości opartych na architekturze dekodera transformer ( , ). Parametry modelu dla tych modeli podano w Tabeli . Dla wszystkich architektur modeli używamy pre-normalizacji ( , ): normalizacja stosowana do wejścia bloków uwagi i MLP. Vaswani et al. 2017 1 Xiong et al. 2020 : Najmniejszy model z rodziny modeli Granite-code jest trenowany z osadzaniem RoPE ( , ) i Multi-Head Attention ( , ). Ten model używa funkcji aktywacji swish ( , ) z GLU ( , ) dla MLP, powszechnie znanej jako swiglu. Do normalizacji używamy RMSNorm ( , ), ponieważ jest bardziej wydajna obliczeniowo niż LayerNorm ( , ). Model 3B jest trenowany z długością kontekstu 2048 tokenów. 3B Su et al. 2023 Vaswani et al. 2017 Ramachandran et al. 2017 Shazeer 2020 Zhang & Sennrich 2019 Ba et al. 2016 : Model 8B ma podobną architekturę jak model 3B, z wyjątkiem użycia Grouped-Query Attention (GQA) ( , ). Użycie GQA zapewnia lepszy kompromis między wydajnością modelu a efektywnością wnioskowania w tej skali. Trenujemy model 8B z długością kontekstu 4096 tokenów. 8B Ainslie et al. 2023 : Model kodu 20B jest trenowany z uczonymi absolutnymi osadzeniami pozycji. Używamy Multi-Query Attention ( , ) podczas treningu dla efektywnego wnioskowania downstream. Dla bloku MLP używamy funkcji aktywacji GELU ( , ). Do normalizacji aktywacji używamy LayerNorm ( , ). Ten model jest trenowany z długością kontekstu 8192 tokenów. 20B Shazeer 2019 Hendrycks & Gimpel 2023 Ba et al. 2016 : Do trenowania modelu 34B postępujemy zgodnie z podejściem dotyczącym skalowania głębokości modelu 20B. W szczególności, najpierw duplikujemy model 20B z 52 warstwami, a następnie usuwamy ostatnie 8 warstw z oryginalnego modelu i pierwsze 8 warstw z jego duplikatu, tworząc dwa modele. 34B Kim et al. Na koniec łączymy oba modele, tworząc model Granite-34B-Code z 88 warstwami (patrz rysunek dla ilustracji). Po skalowaniu głębokości obserwujemy, że spadek wydajności w porównaniu z modelem 20B jest niewielki, w przeciwieństwie do tego, co zaobserwowano u . Wydajność ta jest dość szybko odzyskiwana po kontynuowaniu pre-treningu przeskalowanego modelu 34B. Podobnie jak w przypadku 20B, używamy kontekstu 8192 tokenów podczas pre-treningu. 2 Kim et al. 4 Pre-trening W tej sekcji podajemy szczegóły dotyczące dwufazowego treningu (Sekcja ), celów treningowych (Sekcja ), optymalizacji (Sekcja ) i infrastruktury (Sekcja ) użytej do pre-treningu modeli. 4.1 4.2 4.3 4.4 4.1 Dwufazowy trening Modele Granite Code są trenowane na 3,5-4,5T tokenów danych kodu i danych języka naturalnego związanych z kodem. Dane są tokenizowane za pomocą byte pair encoding (BPE, ( , )), używając tego samego tokenizatora co StarCoder ( , ). Zgodnie z ( , ; , ), wykorzystujemy wysokiej jakości dane w dwóch fazach treningu w następujący sposób. Sennrich et al. 2015 Li et al. 2023a Shen et al. 2024 Hu et al. 2024 • : Podczas fazy 1, zarówno modele 3B, jak i 8B są trenowane na 4 bilionach tokenów danych kodu obejmujących 116 języków. Model o 20 miliardach parametrów jest trenowany na 3 bilionach tokenów kodu. Model 34B jest trenowany na 1,4T tokenów po przeskalowaniu głębokości, które jest wykonywane na punkcie kontrolnym 1,6T modelu 20B. Faza 1 (trening tylko kodu) • : W fazie 2 dodajemy wysokiej jakości publicznie dostępne dane z różnych domen, w tym dokumenty techniczne, matematyczne i internetowe, aby jeszcze bardziej poprawić wydajność modelu w zakresie rozumowania i rozwiązywania problemów, które są niezbędne do generowania kodu. Trenujemy wszystkie nasze modele przez 500B tokenów (80% kodu i 20% danych językowych) w fazie 2 treningu. Faza 2 (trening kodu + języka) 4.2 Cel treningowy Do trenowania wszystkich naszych modeli używamy celu przyczynowego modelowania językowego oraz celu Fill-In-the-Middle (FIM) ( , ). Cel FIM polega na przewidywaniu wstawionych tokenów przy danym kontekście i tekście następującym. Trenujemy nasze modele do pracy z trybami PSM (Prefix-Suffix-Middle) i SPM (Suffix-Prefix-Middle), z odpowiednimi tokenami kontroli formatowania, tak jak w StarCoder ( , ). Bavarian et al. 2022 Li et al. 2023a Ogólna strata jest obliczana jako ważona kombinacja 2 celów: Empirycznie ustaliliśmy = 0,5 podczas treningu i stwierdziliśmy, że działa to dobrze w praktyce, prowadząc do SOTA wydajności zarówno w zadaniach uzupełniania kodu, jak i uzupełniania kodu. Należy zauważyć, że cel FIM jest używany tylko podczas pre-treningu, jednak usuwamy go podczas dostrajania instruktażowego, tj. ustawiamy = 1. α α 4.3 Optymalizacja Używamy optymalizatora AdamW ([Kingma & Ba](#_bookmark80), [2017](#_bookmark80)) z β1 = 0,9, β2 = 0,95 i zanikiem wagi 0,1 do trenowania wszystkich naszych kodowych modeli Granite. W przypadku pre-treningu fazy 1, tempo uczenia podąża za harmonogramem cosinusowym, zaczynając od 3 10−4, które spada do 3 10−5 z początkowym krokiem rozgrzewki liniowej wyn