diff --git a/src/main/cpp/llama.cpp b/src/main/cpp/llama.cpp index 201cc11a..0541f062 160000 --- a/src/main/cpp/llama.cpp +++ b/src/main/cpp/llama.cpp @@ -1 +1 @@ -Subproject commit 201cc11afa0a1950e1f632390b2ac6c937a0d8f0 +Subproject commit 0541f06296753dbc59a57379eb54cec865a4c9f9 diff --git a/src/main/java/ee/carlrobert/codegpt/completions/HuggingFaceModel.java b/src/main/java/ee/carlrobert/codegpt/completions/HuggingFaceModel.java index 5c94dd6e..8ee9308b 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/HuggingFaceModel.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/HuggingFaceModel.java @@ -1,5 +1,6 @@ package ee.carlrobert.codegpt.completions; +import static ee.carlrobert.codegpt.completions.HuggingFaceModel.Model.CST; import static ee.carlrobert.codegpt.completions.HuggingFaceModel.Model.P3M; import static ee.carlrobert.codegpt.completions.HuggingFaceModel.Model.SC3; import static ee.carlrobert.codegpt.completions.llama.LlamaModel.getDownloadedMarker; @@ -132,11 +133,18 @@ public enum HuggingFaceModel { PHI_3_14B_128K_Q5_K_M(P3M, 5, "Phi-3-medium-128k-instruct-Q5_K_M.gguf", 10.1), PHI_3_14B_128K_Q6_K(P3M, 6, "Phi-3-medium-128k-instruct-Q6_K.gguf", 11.5), PHI_3_14B_128K_Q8_0(P3M, 8, "Phi-3-medium-128k-instruct-Q8_0.gguf", 14.8), + + CODESTRAL_22B_32K_Q3_K_M(CST, 3, "Codestral-22B-v0.1-Q3_K_M.gguf", 10.8), + CODESTRAL_22B_32K_Q4_K_M(CST, 4, "Codestral-22B-v0.1-Q4_K_M.gguf", 13.3), + CODESTRAL_22B_32K_Q5_K_M(CST, 5, "Codestral-22B-v0.1-Q5_K_M.gguf", 15.7), + CODESTRAL_22B_32K_Q6_K(CST, 6, "Codestral-22B-v0.1-Q6_K.gguf", 18.3), + CODESTRAL_22B_32K_Q8_0(CST, 8, "Codestral-22B-v0.1-Q8_0.gguf", 23.6), ; enum Model { SC3("bartowski", 3, "stable-code-instruct-3b-GGUF"), - P3M("bartowski", 14, "Phi-3-medium-128k-instruct-GGUF") + P3M("bartowski", 14, "Phi-3-medium-128k-instruct-GGUF"), + CST("bartowski", 22, "Codestral-22B-v0.1-GGUF"), ; private final String user; diff --git a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaModel.java b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaModel.java index 2019ed4d..6e5b6787 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaModel.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaModel.java @@ -188,6 +188,24 @@ public enum LlamaModel { HuggingFaceModel.STABLE_CODE_3B_Q5_K_M, HuggingFaceModel.STABLE_CODE_3B_Q6_K, HuggingFaceModel.STABLE_CODE_3B_Q8_0)), + CODESTRAL( + "Codestral", """ + Codestral is an open-weight generative AI model explicitly designed for code generation \ + tasks. It helps developers write and interact with code through a shared instruction and \ + completion API endpoint. As it masters code and English, it can be used to design advanced \ + AI applications for software developers. Codestral is trained on a diverse dataset of 80+ \ + programming languages. Codestral saves developers time and effort: it can complete coding \ + functions, write tests, and complete any partial code using a fill-in-the-middle mechanism. \ + Interacting with Codestral will help level up the developer’s coding game and reduce the \ + risk of errors and bugs.""", + PromptTemplate.MIXTRAL_INSTRUCT, + InfillPromptTemplate.CODE_GEMMA, + List.of( + HuggingFaceModel.CODESTRAL_22B_32K_Q3_K_M, + HuggingFaceModel.CODESTRAL_22B_32K_Q4_K_M, + HuggingFaceModel.CODESTRAL_22B_32K_Q5_K_M, + HuggingFaceModel.CODESTRAL_22B_32K_Q6_K, + HuggingFaceModel.CODESTRAL_22B_32K_Q8_0)), ; private final String label; diff --git a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/InfillPromptTemplate.kt b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/InfillPromptTemplate.kt index e434418d..f7ff1106 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/InfillPromptTemplate.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/InfillPromptTemplate.kt @@ -34,7 +34,13 @@ enum class InfillPromptTemplate(val label: String, val stopTokens: List? override fun buildPrompt(prefix: String, suffix: String): String { return "<|fim▁begin|>$prefix<|fim▁hole|>$suffix<|fim▁end|>" } - }; + }, + CODESTRAL("Codestral", listOf("")) { + override fun buildPrompt(prefix: String, suffix: String): String { + return "[SUFFIX]$suffix[PREFIX] $prefix" + } + }, + ; abstract fun buildPrompt(prefix: String, suffix: String): String diff --git a/src/test/kotlin/ee/carlrobert/codegpt/completions/PromptTemplateTest.kt b/src/test/kotlin/ee/carlrobert/codegpt/completions/PromptTemplateTest.kt index 1669c247..28f2dce0 100644 --- a/src/test/kotlin/ee/carlrobert/codegpt/completions/PromptTemplateTest.kt +++ b/src/test/kotlin/ee/carlrobert/codegpt/completions/PromptTemplateTest.kt @@ -6,6 +6,7 @@ import ee.carlrobert.codegpt.completions.llama.PromptTemplate.CODE_GEMMA import ee.carlrobert.codegpt.completions.llama.PromptTemplate.CODE_QWEN import ee.carlrobert.codegpt.completions.llama.PromptTemplate.LLAMA import ee.carlrobert.codegpt.completions.llama.PromptTemplate.LLAMA_3 +import ee.carlrobert.codegpt.completions.llama.PromptTemplate.MIXTRAL_INSTRUCT import ee.carlrobert.codegpt.completions.llama.PromptTemplate.PHI_3 import ee.carlrobert.codegpt.completions.llama.PromptTemplate.STABLE_CODE import ee.carlrobert.codegpt.completions.llama.PromptTemplate.TORA @@ -382,6 +383,49 @@ class PromptTemplateTest { """.trimIndent()) } + @Test + fun shouldBuildCodestralPromptWithoutHistory() { + val prompt = MIXTRAL_INSTRUCT.buildPrompt(SYSTEM_PROMPT, USER_PROMPT, listOf()) + + assertThat(prompt).isEqualTo(""" + TEST_SYSTEM_PROMPT + [INST] TEST_USER_PROMPT [/INST]""".trimIndent() + ) + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = [" ", "\t", "\n"]) + fun shouldBuildCodestralPromptWithoutHistorySkippingBlankSystemPrompt(systemPrompt: String?) { + val prompt = MIXTRAL_INSTRUCT.buildPrompt(systemPrompt, USER_PROMPT, listOf()) + + val sysPrompt = if (systemPrompt.isNullOrEmpty()) "" else "$systemPrompt\n" + assertThat(prompt).isEqualTo( + """$sysPrompt[INST] TEST_USER_PROMPT [/INST]""" + ) + } + + @Test + fun shouldBuildCodestral3PromptWithHistory() { + val prompt = MIXTRAL_INSTRUCT.buildPrompt(SYSTEM_PROMPT, USER_PROMPT, HISTORY) + + assertThat(prompt).isEqualTo(""" + TEST_SYSTEM_PROMPT + [INST] TEST_PREV_PROMPT_1 [/INST] TEST_PREV_RESPONSE_1 [INST] TEST_PREV_PROMPT_2 [/INST] TEST_PREV_RESPONSE_2 [INST] TEST_USER_PROMPT [/INST]""".trimIndent()) + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = [" ", "\t", "\n"]) + fun shouldBuildCodestralPromptWithHistorySkippingBlankSystemPrompt(systemPrompt: String?) { + val prompt = MIXTRAL_INSTRUCT.buildPrompt(systemPrompt, USER_PROMPT, HISTORY) + + val sysPrompt = if (systemPrompt.isNullOrEmpty()) "" else "$systemPrompt\n" + assertThat(prompt).isEqualTo( + """$sysPrompt [INST] TEST_PREV_PROMPT_1 [/INST] TEST_PREV_RESPONSE_1 [INST] TEST_PREV_PROMPT_2 [/INST] TEST_PREV_RESPONSE_2 [INST] TEST_USER_PROMPT [/INST]""" + ) + } + @Test fun shouldBuildAlpacaPromptWithHistory() { val prompt = ALPACA.buildPrompt(SYSTEM_PROMPT, USER_PROMPT, HISTORY)