new settings (model path, repeat penalty) w/ tabs

pull/520/head
Aaron Miller 1 year ago committed by AT
parent cd03c5b7d5
commit 15a979b327

@ -27,7 +27,9 @@ Download::Download()
&Download::handleHashAndSaveFinished, Qt::QueuedConnection); &Download::handleHashAndSaveFinished, Qt::QueuedConnection);
connect(&m_networkManager, &QNetworkAccessManager::sslErrors, this, connect(&m_networkManager, &QNetworkAccessManager::sslErrors, this,
&Download::handleSslErrors); &Download::handleSslErrors);
connect(this, &Download::downloadLocalModelsPathChanged, this, &Download::updateModelList);
updateModelList(); updateModelList();
m_downloadLocalModelsPath = defaultLocalModelsPath();
} }
QList<ModelInfo> Download::modelList() const QList<ModelInfo> Download::modelList() const
@ -46,7 +48,22 @@ QList<ModelInfo> Download::modelList() const
return values; return values;
} }
QString Download::downloadLocalModelsPath() const QString Download::downloadLocalModelsPath() const {
return m_downloadLocalModelsPath;
}
void Download::setDownloadLocalModelsPath(const QString &modelPath) {
QString filePath = (modelPath.startsWith("file://") ?
QUrl(modelPath).toLocalFile() : modelPath);
QString canonical = QFileInfo(filePath).canonicalFilePath() + QDir::separator();
qDebug() << "Set model path: " << canonical;
if (m_downloadLocalModelsPath != canonical) {
m_downloadLocalModelsPath = canonical;
emit downloadLocalModelsPathChanged();
}
}
QString Download::defaultLocalModelsPath() const
{ {
QString localPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) QString localPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
+ QDir::separator(); + QDir::separator();

@ -50,6 +50,9 @@ class Download : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QList<ModelInfo> modelList READ modelList NOTIFY modelListChanged) Q_PROPERTY(QList<ModelInfo> modelList READ modelList NOTIFY modelListChanged)
Q_PROPERTY(QString downloadLocalModelsPath READ downloadLocalModelsPath
WRITE setDownloadLocalModelsPath
NOTIFY downloadLocalModelsPathChanged)
public: public:
static Download *globalInstance(); static Download *globalInstance();
@ -58,7 +61,9 @@ public:
Q_INVOKABLE void updateModelList(); Q_INVOKABLE void updateModelList();
Q_INVOKABLE void downloadModel(const QString &modelFile); Q_INVOKABLE void downloadModel(const QString &modelFile);
Q_INVOKABLE void cancelDownload(const QString &modelFile); Q_INVOKABLE void cancelDownload(const QString &modelFile);
Q_INVOKABLE QString defaultLocalModelsPath() const;
Q_INVOKABLE QString downloadLocalModelsPath() const; Q_INVOKABLE QString downloadLocalModelsPath() const;
Q_INVOKABLE void setDownloadLocalModelsPath(const QString &modelPath);
private Q_SLOTS: private Q_SLOTS:
void handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors); void handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
@ -73,6 +78,7 @@ Q_SIGNALS:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal, const QString &modelFile); void downloadProgress(qint64 bytesReceived, qint64 bytesTotal, const QString &modelFile);
void downloadFinished(const QString &modelFile); void downloadFinished(const QString &modelFile);
void modelListChanged(); void modelListChanged();
void downloadLocalModelsPathChanged();
void requestHashAndSave(const QString &hash, const QString &saveFilePath, void requestHashAndSave(const QString &hash, const QString &saveFilePath,
QTemporaryFile *tempFile, QNetworkReply *modelReply); QTemporaryFile *tempFile, QNetworkReply *modelReply);
@ -83,6 +89,7 @@ private:
QMap<QString, ModelInfo> m_modelMap; QMap<QString, ModelInfo> m_modelMap;
QNetworkAccessManager m_networkManager; QNetworkAccessManager m_networkManager;
QMap<QNetworkReply*, QTemporaryFile*> m_activeDownloads; QMap<QNetworkReply*, QTemporaryFile*> m_activeDownloads;
QString m_downloadLocalModelsPath;
private: private:
explicit Download(); explicit Download();

@ -282,7 +282,7 @@ bool LLMObject::handleRecalculate(bool isRecalc)
} }
bool LLMObject::prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p, bool LLMObject::prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p,
float temp, int32_t n_batch) float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens)
{ {
if (!isModelLoaded()) if (!isModelLoaded())
return false; return false;
@ -300,6 +300,8 @@ bool LLMObject::prompt(const QString &prompt, const QString &prompt_template, in
s_ctx.top_p = top_p; s_ctx.top_p = top_p;
s_ctx.temp = temp; s_ctx.temp = temp;
s_ctx.n_batch = n_batch; s_ctx.n_batch = n_batch;
s_ctx.repeat_penalty = repeat_penalty;
s_ctx.repeat_last_n = repeat_penalty_tokens;
m_llmodel->prompt(instructPrompt.toStdString(), responseFunc, recalcFunc, s_ctx); m_llmodel->prompt(instructPrompt.toStdString(), responseFunc, recalcFunc, s_ctx);
m_responseLogits += s_ctx.logits.size() - logitsBefore; m_responseLogits += s_ctx.logits.size() - logitsBefore;
std::string trimmed = trim_whitespace(m_response); std::string trimmed = trim_whitespace(m_response);
@ -345,9 +347,9 @@ bool LLM::isModelLoaded() const
} }
void LLM::prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p, void LLM::prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p,
float temp, int32_t n_batch) float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens)
{ {
emit promptRequested(prompt, prompt_template, n_predict, top_k, top_p, temp, n_batch); emit promptRequested(prompt, prompt_template, n_predict, top_k, top_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens);
} }
void LLM::regenerateResponse() void LLM::regenerateResponse()

@ -38,7 +38,7 @@ public:
public Q_SLOTS: public Q_SLOTS:
bool prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p, bool prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p,
float temp, int32_t n_batch); float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens);
bool loadModel(); bool loadModel();
void modelNameChangeRequested(const QString &modelName); void modelNameChangeRequested(const QString &modelName);
@ -85,7 +85,7 @@ public:
Q_INVOKABLE bool isModelLoaded() const; Q_INVOKABLE bool isModelLoaded() const;
Q_INVOKABLE void prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p, Q_INVOKABLE void prompt(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p,
float temp, int32_t n_batch); float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens);
Q_INVOKABLE void regenerateResponse(); Q_INVOKABLE void regenerateResponse();
Q_INVOKABLE void resetResponse(); Q_INVOKABLE void resetResponse();
Q_INVOKABLE void resetContext(); Q_INVOKABLE void resetContext();
@ -111,7 +111,7 @@ Q_SIGNALS:
void responseChanged(); void responseChanged();
void responseInProgressChanged(); void responseInProgressChanged();
void promptRequested(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p, void promptRequested(const QString &prompt, const QString &prompt_template, int32_t n_predict, int32_t top_k, float top_p,
float temp, int32_t n_batch); float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens);
void regenerateResponseRequested(); void regenerateResponseRequested();
void resetResponseRequested(); void resetResponseRequested();
void resetContextRequested(); void resetContextRequested();

@ -824,7 +824,9 @@ Window {
settingsDialog.maxLength, settingsDialog.maxLength,
settingsDialog.topK, settingsDialog.topP, settingsDialog.topK, settingsDialog.topP,
settingsDialog.temperature, settingsDialog.temperature,
settingsDialog.promptBatchSize) settingsDialog.promptBatchSize,
settingsDialog.repeatPenalty,
settingsDialog.repeatPenaltyTokens)
} }
} }
} }
@ -905,7 +907,9 @@ Window {
settingsDialog.topK, settingsDialog.topK,
settingsDialog.topP, settingsDialog.topP,
settingsDialog.temperature, settingsDialog.temperature,
settingsDialog.promptBatchSize) settingsDialog.promptBatchSize,
settingsDialog.repeatPenalty,
settingsDialog.repeatPenaltyTokens)
textInput.text = "" textInput.text = ""
} }
} }

@ -293,7 +293,7 @@ Dialog {
Label { Label {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("NOTE: models will be downloaded to\n") + Download.downloadLocalModelsPath() text: qsTr("NOTE: models will be downloaded to\n") + Download.downloadLocalModelsPath
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
color: theme.textColor color: theme.textColor

@ -2,6 +2,7 @@ import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Dialogs
import QtQuick.Layouts import QtQuick.Layouts
import download import download
import network import network
@ -31,12 +32,15 @@ Dialog {
property int defaultTopK: 40 property int defaultTopK: 40
property int defaultMaxLength: 4096 property int defaultMaxLength: 4096
property int defaultPromptBatchSize: 9 property int defaultPromptBatchSize: 9
property real defaultRepeatPenalty: 1.10
property int defaultRepeatPenaltyTokens: 64
property int defaultThreadCount: 0 property int defaultThreadCount: 0
property string defaultPromptTemplate: "### Instruction: property string defaultPromptTemplate: "### Instruction:
The prompt below is a question to answer, a task to complete, or a conversation to respond to; decide which and write an appropriate response. The prompt below is a question to answer, a task to complete, or a conversation to respond to; decide which and write an appropriate response.
### Prompt: ### Prompt:
%1 %1
### Response:\n" ### Response:\n"
property string defaultModelPath: Download.defaultLocalModelsPath()
property alias temperature: settings.temperature property alias temperature: settings.temperature
property alias topP: settings.topP property alias topP: settings.topP
@ -44,7 +48,10 @@ The prompt below is a question to answer, a task to complete, or a conversation
property alias maxLength: settings.maxLength property alias maxLength: settings.maxLength
property alias promptBatchSize: settings.promptBatchSize property alias promptBatchSize: settings.promptBatchSize
property alias promptTemplate: settings.promptTemplate property alias promptTemplate: settings.promptTemplate
property alias repeatPenalty: settings.repeatPenalty
property alias repeatPenaltyTokens: settings.repeatPenaltyTokens
property alias threadCount: settings.threadCount property alias threadCount: settings.threadCount
property alias modelPath: settings.modelPath
Settings { Settings {
id: settings id: settings
@ -54,23 +61,34 @@ The prompt below is a question to answer, a task to complete, or a conversation
property int maxLength: settingsDialog.defaultMaxLength property int maxLength: settingsDialog.defaultMaxLength
property int promptBatchSize: settingsDialog.defaultPromptBatchSize property int promptBatchSize: settingsDialog.defaultPromptBatchSize
property int threadCount: settingsDialog.defaultThreadCount property int threadCount: settingsDialog.defaultThreadCount
property real repeatPenalty: settingsDialog.defaultRepeatPenalty
property int repeatPenaltyTokens: settingsDialog.defaultRepeatPenaltyTokens
property string promptTemplate: settingsDialog.defaultPromptTemplate property string promptTemplate: settingsDialog.defaultPromptTemplate
property string modelPath: settingsDialog.defaultModelPath
} }
function restoreDefaults() {
function restoreGenerationDefaults() {
settings.temperature = defaultTemperature; settings.temperature = defaultTemperature;
settings.topP = defaultTopP; settings.topP = defaultTopP;
settings.topK = defaultTopK; settings.topK = defaultTopK;
settings.maxLength = defaultMaxLength; settings.maxLength = defaultMaxLength;
settings.promptBatchSize = defaultPromptBatchSize; settings.promptBatchSize = defaultPromptBatchSize;
settings.promptTemplate = defaultPromptTemplate; settings.promptTemplate = defaultPromptTemplate;
settings.threadCount = defaultThreadCount
settings.sync() settings.sync()
}
function restoreApplicationDefaults() {
settings.modelPath = settingsDialog.defaultModelPath;
settings.threadCount = defaultThreadCount
Download.downloadLocalModelsPath = settings.modelPath;
LLM.threadCount = settings.threadCount; LLM.threadCount = settings.threadCount;
settings.sync()
} }
Component.onCompleted: { Component.onCompleted: {
LLM.threadCount = settings.threadCount; LLM.threadCount = settings.threadCount;
Download.downloadLocalModelsPath = settings.modelPath;
} }
Component.onDestruction: { Component.onDestruction: {
@ -80,260 +98,189 @@ The prompt below is a question to answer, a task to complete, or a conversation
Item { Item {
Accessible.role: Accessible.Dialog Accessible.role: Accessible.Dialog
Accessible.name: qsTr("Settings dialog") Accessible.name: qsTr("Settings dialog")
Accessible.description: qsTr("Dialog containing various settings for model text generation") Accessible.description: qsTr("Dialog containing various application settings")
} }
TabBar {
id: settingsTabBar
width: parent.width
TabButton {
text: qsTr("Generation")
Accessible.role: Accessible.Button
Accessible.name: qsTr("Generation settings")
Accessible.description: qsTr("Settings related to how the model generates text")
}
GridLayout { TabButton {
columns: 2 text: qsTr("Application")
rowSpacing: 2 Accessible.role: Accessible.Button
columnSpacing: 10 Accessible.name: qsTr("Application settings")
anchors.fill: parent Accessible.description: qsTr("Settings related to general behavior of the application")
Label {
id: tempLabel
text: qsTr("Temperature:")
color: theme.textColor
Layout.row: 0
Layout.column: 0
} }
TextField { }
text: settings.temperature.toString()
color: theme.textColor StackLayout {
background: Rectangle { anchors.top: settingsTabBar.bottom
implicitWidth: 150 anchors.bottom: parent.bottom
color: theme.backgroundLighter width: parent.width
radius: 10 currentIndex: settingsTabBar.currentIndex
} Item {
padding: 10 id: generationSettingsTab
ToolTip.text: qsTr("Temperature increases the chances of choosing less likely tokens - higher temperature gives more creative but less predictable outputs") GridLayout {
ToolTip.visible: hovered columns: 2
Layout.row: 0 rowSpacing: 2
Layout.column: 1 columnSpacing: 10
validator: DoubleValidator { } anchors.fill: parent
onAccepted: {
var val = parseFloat(text) Label {
if (!isNaN(val)) { id: tempLabel
settings.temperature = val text: qsTr("Temperature:")
settings.sync() color: theme.textColor
focus = false Layout.row: 0
} else { Layout.column: 0
text = settings.temperature.toString()
} }
} TextField {
Accessible.role: Accessible.EditableText text: settings.temperature.toString()
Accessible.name: tempLabel.text color: theme.textColor
Accessible.description: ToolTip.text background: Rectangle {
} implicitWidth: 150
Label { color: theme.backgroundLighter
id: topPLabel radius: 10
text: qsTr("Top P:") }
color: theme.textColor padding: 10
Layout.row: 1 ToolTip.text: qsTr("Temperature increases the chances of choosing less likely tokens - higher temperature gives more creative but less predictable outputs")
Layout.column: 0 ToolTip.visible: hovered
} Layout.row: 0
TextField { Layout.column: 1
text: settings.topP.toString() validator: DoubleValidator { }
color: theme.textColor onAccepted: {
background: Rectangle { var val = parseFloat(text)
implicitWidth: 150 if (!isNaN(val)) {
color: theme.backgroundLighter settings.temperature = val
radius: 10 settings.sync()
} focus = false
padding: 10 } else {
ToolTip.text: qsTr("Only the most likely tokens up to a total probability of top_p can be chosen, prevents choosing highly unlikely tokens, aka Nucleus Sampling") text = settings.temperature.toString()
ToolTip.visible: hovered }
Layout.row: 1 }
Layout.column: 1 Accessible.role: Accessible.EditableText
validator: DoubleValidator {} Accessible.name: tempLabel.text
onAccepted: { Accessible.description: ToolTip.text
var val = parseFloat(text)
if (!isNaN(val)) {
settings.topP = val
settings.sync()
focus = false
} else {
text = settings.topP.toString()
} }
} Label {
Accessible.role: Accessible.EditableText id: topPLabel
Accessible.name: topPLabel.text text: qsTr("Top P:")
Accessible.description: ToolTip.text color: theme.textColor
} Layout.row: 1
Label { Layout.column: 0
id: topKLabel }
text: qsTr("Top K:") TextField {
color: theme.textColor text: settings.topP.toString()
Layout.row: 2 color: theme.textColor
Layout.column: 0 background: Rectangle {
} implicitWidth: 150
TextField { color: theme.backgroundLighter
text: settings.topK.toString() radius: 10
color: theme.textColor }
background: Rectangle { padding: 10
implicitWidth: 150 ToolTip.text: qsTr("Only the most likely tokens up to a total probability of top_p can be chosen, prevents choosing highly unlikely tokens, aka Nucleus Sampling")
color: theme.backgroundLighter ToolTip.visible: hovered
radius: 10 Layout.row: 1
} Layout.column: 1
padding: 10 validator: DoubleValidator {}
ToolTip.text: qsTr("Only the top K most likely tokens will be chosen from") onAccepted: {
ToolTip.visible: hovered var val = parseFloat(text)
Layout.row: 2 if (!isNaN(val)) {
Layout.column: 1 settings.topP = val
validator: IntValidator { bottom: 1 } settings.sync()
onAccepted: { focus = false
var val = parseInt(text) } else {
if (!isNaN(val)) { text = settings.topP.toString()
settings.topK = val }
settings.sync() }
focus = false Accessible.role: Accessible.EditableText
} else { Accessible.name: topPLabel.text
text = settings.topK.toString() Accessible.description: ToolTip.text
}
Label {
id: topKLabel
text: qsTr("Top K:")
color: theme.textColor
Layout.row: 2
Layout.column: 0
} }
} TextField {
Accessible.role: Accessible.EditableText text: settings.topK.toString()
Accessible.name: topKLabel.text color: theme.textColor
Accessible.description: ToolTip.text background: Rectangle {
} implicitWidth: 150
Label { color: theme.backgroundLighter
id: maxLengthLabel radius: 10
text: qsTr("Max Length:") }
color: theme.textColor padding: 10
Layout.row: 3 ToolTip.text: qsTr("Only the top K most likely tokens will be chosen from")
Layout.column: 0 ToolTip.visible: hovered
} Layout.row: 2
TextField { Layout.column: 1
text: settings.maxLength.toString() validator: IntValidator { bottom: 1 }
color: theme.textColor onAccepted: {
background: Rectangle { var val = parseInt(text)
implicitWidth: 150 if (!isNaN(val)) {
color: theme.backgroundLighter settings.topK = val
radius: 10 settings.sync()
} focus = false
padding: 10 } else {
ToolTip.text: qsTr("Maximum length of response in tokens") text = settings.topK.toString()
ToolTip.visible: hovered }
Layout.row: 3 }
Layout.column: 1 Accessible.role: Accessible.EditableText
validator: IntValidator { bottom: 1 } Accessible.name: topKLabel.text
onAccepted: { Accessible.description: ToolTip.text
var val = parseInt(text)
if (!isNaN(val)) {
settings.maxLength = val
settings.sync()
focus = false
} else {
text = settings.maxLength.toString()
} }
} Label {
Accessible.role: Accessible.EditableText id: maxLengthLabel
Accessible.name: maxLengthLabel.text text: qsTr("Max Length:")
Accessible.description: ToolTip.text color: theme.textColor
} Layout.row: 3
Layout.column: 0
Label {
id: batchSizeLabel
text: qsTr("Prompt Batch Size:")
color: theme.textColor
Layout.row: 4
Layout.column: 0
}
TextField {
text: settings.promptBatchSize.toString()
color: theme.textColor
background: Rectangle {
implicitWidth: 150
color: theme.backgroundLighter
radius: 10
}
padding: 10
ToolTip.text: qsTr("Amount of prompt tokens to process at once, higher values can speed up reading prompts but will use more RAM")
ToolTip.visible: hovered
Layout.row: 4
Layout.column: 1
validator: IntValidator { bottom: 1 }
onAccepted: {
var val = parseInt(text)
if (!isNaN(val)) {
settings.promptBatchSize = val
settings.sync()
focus = false
} else {
text = settings.promptBatchSize.toString()
} }
} TextField {
Accessible.role: Accessible.EditableText text: settings.maxLength.toString()
Accessible.name: batchSizeLabel.text color: theme.textColor
Accessible.description: ToolTip.text background: Rectangle {
} implicitWidth: 150
color: theme.backgroundLighter
Label { radius: 10
id: nThreadsLabel }
text: qsTr("CPU Threads") padding: 10
color: theme.textColor ToolTip.text: qsTr("Maximum length of response in tokens")
Layout.row: 5 ToolTip.visible: hovered
Layout.column: 0 Layout.row: 3
} Layout.column: 1
TextField { validator: IntValidator { bottom: 1 }
text: settingsDialog.threadCount.toString() onAccepted: {
color: theme.textColor var val = parseInt(text)
background: Rectangle { if (!isNaN(val)) {
implicitWidth: 150 settings.maxLength = val
color: theme.backgroundLighter settings.sync()
radius: 10 focus = false
} } else {
padding: 10 text = settings.maxLength.toString()
ToolTip.text: qsTr("Amount of processing threads to use, a setting of 0 will use the lesser of 4 or your number of CPU threads") }
ToolTip.visible: hovered }
Layout.row: 5 Accessible.role: Accessible.EditableText
Layout.column: 1 Accessible.name: maxLengthLabel.text
validator: IntValidator { bottom: 1 } Accessible.description: ToolTip.text
onAccepted: {
var val = parseInt(text)
if (!isNaN(val)) {
settingsDialog.threadCount = val
LLM.threadCount = val
focus = false
} else {
text = settingsDialog.threadCount.toString()
} }
}
Accessible.role: Accessible.EditableText
Accessible.name: nThreadsLabel.text
Accessible.description: ToolTip.text
}
Label { Label {
id: promptTemplateLabel id: batchSizeLabel
text: qsTr("Prompt Template:") text: qsTr("Prompt Batch Size:")
color: theme.textColor color: theme.textColor
Layout.row: 6 Layout.row: 4
Layout.column: 0 Layout.column: 0
} }
Rectangle { TextField {
Layout.row: 6 text: settings.promptBatchSize.toString()
Layout.column: 1
Layout.fillWidth: true
height: 200
color: "transparent"
clip: true
Label {
id: promptTemplateLabelHelp
visible: settings.promptTemplate.indexOf("%1") === -1
font.bold: true
color: theme.textErrorColor
text: qsTr("Prompt template must contain %1 to be replaced with the user's input.")
anchors.fill: templateScrollView
z: 200
padding: 10
wrapMode: TextArea.Wrap
Accessible.role: Accessible.EditableText
Accessible.name: text
}
ScrollView {
id: templateScrollView
anchors.fill: parent
TextArea {
text: settings.promptTemplate
color: theme.textColor color: theme.textColor
background: Rectangle { background: Rectangle {
implicitWidth: 150 implicitWidth: 150
@ -341,42 +288,275 @@ The prompt below is a question to answer, a task to complete, or a conversation
radius: 10 radius: 10
} }
padding: 10 padding: 10
wrapMode: TextArea.Wrap ToolTip.text: qsTr("Amount of prompt tokens to process at once, higher values can speed up reading prompts but will use more RAM")
onTextChanged: { ToolTip.visible: hovered
settings.promptTemplate = text Layout.row: 4
settings.sync() Layout.column: 1
validator: IntValidator { bottom: 1 }
onAccepted: {
var val = parseInt(text)
if (!isNaN(val)) {
settings.promptBatchSize = val
settings.sync()
focus = false
} else {
text = settings.promptBatchSize.toString()
}
}
Accessible.role: Accessible.EditableText
Accessible.name: batchSizeLabel.text
Accessible.description: ToolTip.text
}
Label {
id: repeatPenaltyLabel
text: qsTr("Repeat Penalty:")
color: theme.textColor
Layout.row: 5
Layout.column: 0
}
TextField {
text: settings.repeatPenalty.toString()
color: theme.textColor
background: Rectangle {
implicitWidth: 150
color: theme.backgroundLighter
radius: 10
}
padding: 10
ToolTip.text: qsTr("Amount to penalize reptetitiveness of the output")
ToolTip.visible: hovered
Layout.row: 5
Layout.column: 1
validator: DoubleValidator {}
onAccepted: {
var val = parseFloat(text)
if (!isNaN(val)) {
settings.repeatPenalty = val
settings.sync()
focus = false
} else {
text = settings.repeatPenalty.toString()
}
} }
bottomPadding: 10
Accessible.role: Accessible.EditableText Accessible.role: Accessible.EditableText
Accessible.name: promptTemplateLabel.text Accessible.name: repeatPenaltyLabel.text
Accessible.description: promptTemplateLabelHelp.text Accessible.description: ToolTip.text
} }
} Label {
} id: repeatPenaltyTokensLabel
Button { text: qsTr("Repeat Penalty Tokens:")
Layout.row: 7 color: theme.textColor
Layout.column: 1 Layout.row: 6
Layout.fillWidth: true Layout.column: 0
padding: 15 }
contentItem: Text { TextField {
text: qsTr("Restore Defaults") text: settings.repeatPenaltyTokens.toString()
horizontalAlignment: Text.AlignHCenter color: theme.textColor
color: theme.textColor background: Rectangle {
Accessible.role: Accessible.Button implicitWidth: 150
Accessible.name: text color: theme.backgroundLighter
Accessible.description: qsTr("Restores the settings dialog to a default state") radius: 10
} }
padding: 10
ToolTip.text: qsTr("How far back in output to apply repeat penalty")
ToolTip.visible: hovered
Layout.row: 6
Layout.column: 1
validator: IntValidator { bottom: 1 }
onAccepted: {
var val = parseInt(text)
if (!isNaN(val)) {
settings.repeatPenaltyTokens = val
settings.sync()
focus = false
} else {
text = settings.repeatPenaltyTokens.toString()
}
}
Accessible.role: Accessible.EditableText
Accessible.name: repeatPenaltyTokensLabel.text
Accessible.description: ToolTip.text
}
background: Rectangle { Label {
opacity: .5 id: promptTemplateLabel
border.color: theme.backgroundLightest text: qsTr("Prompt Template:")
border.width: 1 color: theme.textColor
radius: 10 Layout.row: 7
color: theme.backgroundLight Layout.column: 0
} }
onClicked: { Rectangle {
settingsDialog.restoreDefaults() Layout.row: 7
} Layout.column: 1
} Layout.fillWidth: true
height: 200
color: "transparent"
clip: true
Label {
id: promptTemplateLabelHelp
visible: settings.promptTemplate.indexOf("%1") === -1
font.bold: true
color: theme.textErrorColor
text: qsTr("Prompt template must contain %1 to be replaced with the user's input.")
anchors.fill: templateScrollView
z: 200
padding: 10
wrapMode: TextArea.Wrap
Accessible.role: Accessible.EditableText
Accessible.name: text
}
ScrollView {
id: templateScrollView
anchors.fill: parent
TextArea {
text: settings.promptTemplate
color: theme.textColor
background: Rectangle {
implicitWidth: 150
color: theme.backgroundLighter
radius: 10
}
padding: 10
wrapMode: TextArea.Wrap
onTextChanged: {
settings.promptTemplate = text
settings.sync()
}
bottomPadding: 10
Accessible.role: Accessible.EditableText
Accessible.name: promptTemplateLabel.text
Accessible.description: promptTemplateLabelHelp.text
}
}
}
Button {
Layout.row: 8
Layout.column: 1
Layout.fillWidth: true
padding: 15
contentItem: Text {
text: qsTr("Restore Defaults")
horizontalAlignment: Text.AlignHCenter
color: theme.textColor
Accessible.role: Accessible.Button
Accessible.name: text
Accessible.description: qsTr("Restores the settings dialog to a default state")
}
background: Rectangle {
opacity: .5
border.color: theme.backgroundLightest
border.width: 1
radius: 10
color: theme.backgroundLight
}
onClicked: {
settingsDialog.restoreGenerationDefaults()
}
}
}
}
Item {
id: systemSettingsTab
GridLayout {
columns: 3
rowSpacing: 2
columnSpacing: 10
width: parent.width
anchors.top: parent.top
FolderDialog {
id: modelPathDialog
title: "Please choose a directory"
onAccepted: {
Download.downloadLocalModelsPath = selectedFolder
settings.modelPath = Download.downloadLocalModelsPath
settings.sync()
}
}
Label {
id: modelPathLabel
text: qsTr("Model file path:")
color: theme.textColor
Layout.row: 1
Layout.column: 0
}
TextField {
id: modelPathDisplayLabel
text: settings.modelPath
color: theme.textColor
readOnly: true
Layout.row: 1
Layout.column: 1
}
Button {
Layout.row: 1
Layout.column: 2
text: qsTr("Browse")
onClicked: modelPathDialog.open()
}
Label {
id: nThreadsLabel
text: qsTr("CPU Threads:")
color: theme.textColor
Layout.row: 2
Layout.column: 0
}
TextField {
text: settingsDialog.threadCount.toString()
color: theme.textColor
background: Rectangle {
implicitWidth: 150
color: theme.backgroundLighter
radius: 10
}
padding: 10
ToolTip.text: qsTr("Amount of processing threads to use, a setting of 0 will use the lesser of 4 or your number of CPU threads")
ToolTip.visible: hovered
Layout.row: 2
Layout.column: 1
validator: IntValidator { bottom: 1 }
onAccepted: {
var val = parseInt(text)
if (!isNaN(val)) {
settingsDialog.threadCount = val
LLM.threadCount = val
settings.sync()
focus = false
} else {
text = settingsDialog.threadCount.toString()
}
}
Accessible.role: Accessible.EditableText
Accessible.name: nThreadsLabel.text
Accessible.description: ToolTip.text
}
Button {
Layout.row: 3
Layout.column: 1
Layout.fillWidth: true
padding: 15
contentItem: Text {
text: qsTr("Restore Defaults")
horizontalAlignment: Text.AlignHCenter
color: theme.textColor
Accessible.role: Accessible.Button
Accessible.name: text
Accessible.description: qsTr("Restores the settings dialog to a default state")
}
background: Rectangle {
opacity: .5
border.color: theme.backgroundLightest
border.width: 1
radius: 10
color: theme.backgroundLight
}
onClicked: {
settingsDialog.restoreApplicationDefaults()
}
}
}
}
} }
} }

Loading…
Cancel
Save