From 0e61bee0f821ff2fd5e7632e117c69b387b9105d Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Sun, 3 Dec 2023 18:10:39 +0200 Subject: [PATCH] feat: improve llama server logging --- .../completions/llama/LlamaServerAgent.java | 80 +++++++++++-------- .../llama/LlamaServerStartupParams.java | 45 +++++++++++ .../service/LlamaServiceSelectionForm.java | 21 +++-- .../resources/messages/codegpt.properties | 5 +- 4 files changed, 112 insertions(+), 39 deletions(-) create mode 100644 src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java diff --git a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java index 7216ef42..91b7d162 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java @@ -1,5 +1,7 @@ package ee.carlrobert.codegpt.completions.llama; +import static java.lang.String.format; + import com.fasterxml.jackson.databind.ObjectMapper; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; @@ -9,18 +11,21 @@ import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessListener; import com.intellij.execution.process.ProcessOutputType; import com.intellij.icons.AllIcons.Actions; +import com.intellij.notification.NotificationType; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.Service; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; import com.intellij.ui.components.JBLabel; +import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.CodeGPTPlugin; -import ee.carlrobert.codegpt.settings.service.LlamaServiceSelectionForm; import ee.carlrobert.codegpt.settings.service.ServerProgressPanel; import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; +import ee.carlrobert.codegpt.util.OverlayUtil; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import javax.swing.SwingConstants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,19 +35,20 @@ public final class LlamaServerAgent implements Disposable { private static final Logger LOG = Logger.getInstance(LlamaServerAgent.class); - private static @Nullable OSProcessHandler makeProcessHandler; - private static @Nullable OSProcessHandler startServerProcessHandler; + private @Nullable OSProcessHandler makeProcessHandler; + private @Nullable OSProcessHandler startServerProcessHandler; public void startAgent( - LlamaServiceSelectionForm llamaServiceSelectionForm, + LlamaServerStartupParams params, ServerProgressPanel serverProgressPanel, Runnable onSuccess) { ApplicationManager.getApplication().invokeLater(() -> { try { - serverProgressPanel.updateText("Building llama.cpp..."); + serverProgressPanel.updateText( + CodeGPTBundle.get("llamaServerAgent.buildingProject.description")); makeProcessHandler = new OSProcessHandler(getMakeCommandLinde()); makeProcessHandler.addProcessListener( - getMakeProcessListener(llamaServiceSelectionForm, serverProgressPanel, onSuccess)); + getMakeProcessListener(params, serverProgressPanel, onSuccess)); makeProcessHandler.startNotify(); } catch (ExecutionException e) { throw new RuntimeException(e); @@ -63,9 +69,11 @@ public final class LlamaServerAgent implements Disposable { } private ProcessListener getMakeProcessListener( - LlamaServiceSelectionForm serviceSelectionForm, + LlamaServerStartupParams params, ServerProgressPanel serverProgressPanel, Runnable onSuccess) { + LOG.info("Building llama project"); + return new ProcessAdapter() { @Override public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { @@ -75,21 +83,16 @@ public final class LlamaServerAgent implements Disposable { @Override public void processTerminated(@NotNull ProcessEvent event) { try { - serverProgressPanel.updateText("Booting up server..."); - startServerProcessHandler = new OSProcessHandler.Silent( - getServerCommandLine( - serviceSelectionForm.getLlamaModelPreferencesForm().getActualModelPath(), - serviceSelectionForm.getContextSize(), - serviceSelectionForm.getThreads(), - serviceSelectionForm.getServerPort(), - serviceSelectionForm.getListOfAdditionalParameters())); - startServerProcessHandler.addProcessListener(getProcessListener( - serviceSelectionForm.getServerPort(), - serverProgressPanel, - onSuccess)); + LOG.info("Booting up llama server"); + + serverProgressPanel.updateText( + CodeGPTBundle.get("llamaServerAgent.serverBootup.description")); + startServerProcessHandler = new OSProcessHandler.Silent(getServerCommandLine(params)); + startServerProcessHandler.addProcessListener( + getProcessListener(params.getPort(), serverProgressPanel, onSuccess)); startServerProcessHandler.startNotify(); } catch (ExecutionException ex) { - LOG.error("Unable to start the server", ex); + LOG.error("Unable to start llama server", ex); throw new RuntimeException(ex); } } @@ -102,9 +105,18 @@ public final class LlamaServerAgent implements Disposable { Runnable onSuccess) { return new ProcessAdapter() { private final ObjectMapper objectMapper = new ObjectMapper(); + private final List errorLines = new CopyOnWriteArrayList<>(); @Override public void processTerminated(@NotNull ProcessEvent event) { + if (errorLines.isEmpty()) { + LOG.info(format("Server terminated with code %d", event.getExitCode())); + } else { + var error = String.join("", errorLines); + OverlayUtil.showNotification(error, NotificationType.ERROR); + LOG.error(error); + } + serverProgressPanel.displayComponent(new JBLabel( "Server terminated", Actions.Cancel, @@ -113,12 +125,19 @@ public final class LlamaServerAgent implements Disposable { @Override public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { - LOG.debug(event.getText()); + if (ProcessOutputType.isStderr(outputType)) { + errorLines.add(event.getText()); + return; + } + + if (ProcessOutputType.isStdout(outputType)) { + LOG.info(event.getText()); - if (outputType == ProcessOutputType.STDOUT) { try { var serverMessage = objectMapper.readValue(event.getText(), LlamaServerMessage.class); if ("HTTP server listening".equals(serverMessage.getMessage())) { + LOG.info("Server up and running!"); + LlamaSettingsState.getInstance().setServerPort(port); onSuccess.run(); } @@ -139,21 +158,16 @@ public final class LlamaServerAgent implements Disposable { return commandLine; } - private GeneralCommandLine getServerCommandLine( - String modelPath, - int contextLength, - int threads, - int port, - List additionalParameters) { + private GeneralCommandLine getServerCommandLine(LlamaServerStartupParams params) { GeneralCommandLine commandLine = new GeneralCommandLine().withCharset(StandardCharsets.UTF_8); commandLine.setExePath("./server"); commandLine.withWorkDirectory(CodeGPTPlugin.getLlamaSourcePath()); commandLine.addParameters( - "-m", modelPath, - "-c", String.valueOf(contextLength), - "--port", String.valueOf(port), - "-t", String.valueOf(threads)); - commandLine.addParameters(additionalParameters); + "-m", params.getModelPath(), + "-c", String.valueOf(params.getContextLength()), + "--port", String.valueOf(params.getPort()), + "-t", String.valueOf(params.getThreads())); + commandLine.addParameters(params.getAdditionalParameters()); commandLine.setRedirectErrorStream(false); return commandLine; } diff --git a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java new file mode 100644 index 00000000..5ea26679 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java @@ -0,0 +1,45 @@ +package ee.carlrobert.codegpt.completions.llama; + +import java.util.List; + +public class LlamaServerStartupParams { + + private final String modelPath; + private final int contextLength; + private final int threads; + private final int port; + private final List additionalParameters; + + public LlamaServerStartupParams( + String modelPath, + int contextLength, + int threads, + int port, + List additionalParameters) { + this.modelPath = modelPath; + this.contextLength = contextLength; + this.threads = threads; + this.port = port; + this.additionalParameters = additionalParameters; + } + + public String getModelPath() { + return modelPath; + } + + public int getContextLength() { + return contextLength; + } + + public int getThreads() { + return threads; + } + + public int getPort() { + return port; + } + + public List getAdditionalParameters() { + return additionalParameters; + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServiceSelectionForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServiceSelectionForm.java index 663bd10b..3d7b82eb 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServiceSelectionForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServiceSelectionForm.java @@ -18,6 +18,7 @@ import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.CodeGPTPlugin; import ee.carlrobert.codegpt.completions.HuggingFaceModel; import ee.carlrobert.codegpt.completions.llama.LlamaServerAgent; +import ee.carlrobert.codegpt.completions.llama.LlamaServerStartupParams; import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; import ee.carlrobert.codegpt.util.OverlayUtil; import java.awt.BorderLayout; @@ -179,11 +180,21 @@ public class LlamaServiceSelectionForm extends JPanel { llamaServerAgent.stopAgent(); } else { disableForm(serverButton, serverProgressPanel); - llamaServerAgent.startAgent(this, serverProgressPanel, () -> { - setFormEnabled(false); - serverProgressPanel.displayComponent( - new JBLabel("Server running", Actions.Checked, SwingConstants.LEADING)); - }); + llamaServerAgent.startAgent( + new LlamaServerStartupParams( + llamaModelPreferencesForm.getActualModelPath(), + getContextSize(), + getThreads(), + getServerPort(), + getListOfAdditionalParameters()), + serverProgressPanel, + () -> { + setFormEnabled(false); + serverProgressPanel.displayComponent(new JBLabel( + CodeGPTBundle.get("settingsConfigurable.service.llama.progress.serverRunning"), + Actions.Checked, + SwingConstants.LEADING)); + }); } }); return serverButton; diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index 03a6b3ac..d51bcff1 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -43,11 +43,12 @@ settingsConfigurable.service.llama.contextSize.label=Prompt context size: settingsConfigurable.service.llama.contextSize.comment=The size of the prompt context. LLaMA models were built with a context of 2048, which will provide better results for longer input/inference. settingsConfigurable.service.llama.threads.label=Threads: settingsConfigurable.service.llama.threads.comment=The number of threads available to execute the model. It is not recommended to specify a number greater than the number of processor cores. -settingsConfigurable.service.llama.additionalParameters.label=Additional parameters +settingsConfigurable.service.llama.additionalParameters.label=Additional parameters: settingsConfigurable.service.llama.additionalParameters.comment=Additional command-line parameters for the server startup process, separated by commas. See the full list of options.

Example: "--n-gpu-layers, 1, --no-mmap, --mlock"

settingsConfigurable.service.llama.port.label=Port: settingsConfigurable.service.llama.startServer.label=Start server settingsConfigurable.service.llama.stopServer.label=Stop server +settingsConfigurable.service.llama.progress.serverRunning=Server running settingsConfigurable.service.llama.progress.stoppingServer=Stopping a server... settingsConfigurable.service.llama.progress.startingServer=Starting a server... settingsConfigurable.service.llama.progress.downloadingModel.title=Downloading Model @@ -134,3 +135,5 @@ checkForUpdatesTask.title=Checking for CodeGPT update... checkForUpdatesTask.notification.message=An update for CodeGPT is available. checkForUpdatesTask.notification.installButton=Install update checkForUpdatesTask.notification.hideButton=Do not show again +llamaServerAgent.buildingProject.description=Building llama.cpp... +llamaServerAgent.serverBootup.description=Booting up server... \ No newline at end of file