qml: improve chats with missing models and model settings layout (#2520)

Signed-off-by: Jared Van Bortel <jared@nomic.ai>
This commit is contained in:
Jared Van Bortel 2024-07-08 17:01:30 -04:00 committed by GitHub
parent 11b58a1a15
commit 4853adebd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 41 deletions

View File

@ -204,7 +204,7 @@ Window {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
width: 16 + 52 * theme.fontScale width: 68 * theme.fontScale
color: theme.viewBarBackground color: theme.viewBarBackground
ColumnLayout { ColumnLayout {

View File

@ -47,6 +47,10 @@ Rectangle {
return ModelList.modelInfo(currentChat.modelInfo.id).name; return ModelList.modelInfo(currentChat.modelInfo.id).name;
} }
function currentModelInstalled() {
return currentModelName() !== "" && ModelList.modelInfo(currentChat.modelInfo.id).installed;
}
PopupDialog { PopupDialog {
id: modelLoadingErrorPopup id: modelLoadingErrorPopup
anchors.centerIn: parent anchors.centerIn: parent
@ -322,7 +326,7 @@ Rectangle {
visible: currentChat.modelLoadingError === "" visible: currentChat.modelLoadingError === ""
&& !currentChat.trySwitchContextInProgress && !currentChat.trySwitchContextInProgress
&& !currentChat.isCurrentlyLoading && !currentChat.isCurrentlyLoading
&& (currentChat.isModelLoaded || currentModelName() !== "") && (currentChat.isModelLoaded || currentModelInstalled())
source: "qrc:/gpt4all/icons/regenerate.svg" source: "qrc:/gpt4all/icons/regenerate.svg"
backgroundColor: theme.textColor backgroundColor: theme.textColor
backgroundColorHovered: theme.styledTextColor backgroundColorHovered: theme.styledTextColor
@ -358,15 +362,17 @@ Rectangle {
rightPadding: 10 rightPadding: 10
text: { text: {
if (ModelList.selectableModels.count === 0) if (ModelList.selectableModels.count === 0)
return qsTr("No model installed...") return qsTr("No model installed.")
if (currentChat.modelLoadingError !== "") if (currentChat.modelLoadingError !== "")
return qsTr("Model loading error...") return qsTr("Model loading error.")
if (currentChat.trySwitchContextInProgress === 1) if (currentChat.trySwitchContextInProgress === 1)
return qsTr("Waiting for model...") return qsTr("Waiting for model...")
if (currentChat.trySwitchContextInProgress === 2) if (currentChat.trySwitchContextInProgress === 2)
return qsTr("Switching context...") return qsTr("Switching context...")
if (currentModelName() === "") if (currentModelName() === "")
return qsTr("Choose a model...") return qsTr("Choose a model...")
if (!currentModelInstalled())
return qsTr("Not found: %1").arg(currentModelName())
if (currentChat.modelLoadingPercentage === 0.0) if (currentChat.modelLoadingPercentage === 0.0)
return qsTr("Reload \u00B7 ") + currentModelName() return qsTr("Reload \u00B7 ") + currentModelName()
if (currentChat.isCurrentlyLoading) if (currentChat.isCurrentlyLoading)
@ -1519,7 +1525,7 @@ Rectangle {
&& currentChat.modelLoadingError === "" && currentChat.modelLoadingError === ""
&& !currentChat.trySwitchContextInProgress && !currentChat.trySwitchContextInProgress
&& !currentChat.isCurrentlyLoading && !currentChat.isCurrentlyLoading
&& currentModelName() !== "" && currentModelInstalled()
Image { Image {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View File

@ -303,48 +303,58 @@ MySettingsTab {
helpText: qsTr("Number of input and output tokens the model sees.") helpText: qsTr("Number of input and output tokens the model sees.")
Layout.row: 0 Layout.row: 0
Layout.column: 0 Layout.column: 0
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { Item {
id: contextLengthField
visible: !root.currentModelInfo.isOnline
text: root.currentModelInfo.contextLength
font.pixelSize: theme.fontSizeLarge
color: theme.textColor
ToolTip.text: qsTr("Maximum combined prompt/response tokens before information is lost.\nUsing more context than the model was trained on will yield poor results.\nNOTE: Does not take effect until you reload the model.")
ToolTip.visible: hovered
Layout.row: 0 Layout.row: 0
Layout.column: 1 Layout.column: 1
Connections { Layout.fillWidth: true
target: MySettings Layout.maximumWidth: 200
function onContextLengthChanged() { Layout.margins: 0
contextLengthField.text = root.currentModelInfo.contextLength; height: contextLengthField.height
}
} MyTextField {
Connections { id: contextLengthField
target: root anchors.left: parent.left
function onCurrentModelInfoChanged() { anchors.verticalCenter: parent.verticalCenter
contextLengthField.text = root.currentModelInfo.contextLength; visible: !root.currentModelInfo.isOnline
} text: root.currentModelInfo.contextLength
} font.pixelSize: theme.fontSizeLarge
onEditingFinished: { color: theme.textColor
var val = parseInt(text) ToolTip.text: qsTr("Maximum combined prompt/response tokens before information is lost.\nUsing more context than the model was trained on will yield poor results.\nNOTE: Does not take effect until you reload the model.")
if (isNaN(val)) { ToolTip.visible: hovered
text = root.currentModelInfo.contextLength Connections {
} else { target: MySettings
if (val < 8) { function onContextLengthChanged() {
val = 8 contextLengthField.text = root.currentModelInfo.contextLength;
contextLengthField.text = val
} else if (val > root.currentModelInfo.maxContextLength) {
val = root.currentModelInfo.maxContextLength
contextLengthField.text = val
} }
MySettings.setModelContextLength(root.currentModelInfo, val)
focus = false
} }
Connections {
target: root
function onCurrentModelInfoChanged() {
contextLengthField.text = root.currentModelInfo.contextLength;
}
}
onEditingFinished: {
var val = parseInt(text)
if (isNaN(val)) {
text = root.currentModelInfo.contextLength
} else {
if (val < 8) {
val = 8
contextLengthField.text = val
} else if (val > root.currentModelInfo.maxContextLength) {
val = root.currentModelInfo.maxContextLength
contextLengthField.text = val
}
MySettings.setModelContextLength(root.currentModelInfo, val)
focus = false
}
}
Accessible.role: Accessible.EditableText
Accessible.name: contextLengthLabel.text
Accessible.description: ToolTip.text
} }
Accessible.role: Accessible.EditableText
Accessible.name: contextLengthLabel.text
Accessible.description: ToolTip.text
} }
MySettingsLabel { MySettingsLabel {
@ -353,6 +363,7 @@ MySettingsTab {
helpText: qsTr("Randomness of model output. Higher -> more variation.") helpText: qsTr("Randomness of model output. Higher -> more variation.")
Layout.row: 1 Layout.row: 1
Layout.column: 2 Layout.column: 2
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
@ -398,6 +409,7 @@ MySettingsTab {
helpText: qsTr("Nucleus Sampling factor. Lower -> more predicatable.") helpText: qsTr("Nucleus Sampling factor. Lower -> more predicatable.")
Layout.row: 2 Layout.row: 2
Layout.column: 0 Layout.column: 0
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: topPField id: topPField
@ -442,6 +454,7 @@ MySettingsTab {
helpText: qsTr("Minimum token probability. Higher -> more predictable.") helpText: qsTr("Minimum token probability. Higher -> more predictable.")
Layout.row: 3 Layout.row: 3
Layout.column: 0 Layout.column: 0
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: minPField id: minPField
@ -488,6 +501,7 @@ MySettingsTab {
helpText: qsTr("Size of selection pool for tokens.") helpText: qsTr("Size of selection pool for tokens.")
Layout.row: 2 Layout.row: 2
Layout.column: 2 Layout.column: 2
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: topKField id: topKField
@ -534,6 +548,7 @@ MySettingsTab {
helpText: qsTr("Maximum response length, in tokens.") helpText: qsTr("Maximum response length, in tokens.")
Layout.row: 0 Layout.row: 0
Layout.column: 2 Layout.column: 2
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: maxLengthField id: maxLengthField
@ -579,6 +594,7 @@ MySettingsTab {
helpText: qsTr("The batch size used for prompt processing.") helpText: qsTr("The batch size used for prompt processing.")
Layout.row: 1 Layout.row: 1
Layout.column: 0 Layout.column: 0
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: batchSizeField id: batchSizeField
@ -625,6 +641,7 @@ MySettingsTab {
helpText: qsTr("Repetition penalty factor. Set to 1 to disable.") helpText: qsTr("Repetition penalty factor. Set to 1 to disable.")
Layout.row: 4 Layout.row: 4
Layout.column: 2 Layout.column: 2
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: repeatPenaltyField id: repeatPenaltyField
@ -669,6 +686,7 @@ MySettingsTab {
helpText: qsTr("Number of previous tokens used for penalty.") helpText: qsTr("Number of previous tokens used for penalty.")
Layout.row: 3 Layout.row: 3
Layout.column: 2 Layout.column: 2
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: repeatPenaltyTokenField id: repeatPenaltyTokenField
@ -714,6 +732,7 @@ MySettingsTab {
helpText: qsTr("Number of model layers to load into VRAM.") helpText: qsTr("Number of model layers to load into VRAM.")
Layout.row: 4 Layout.row: 4
Layout.column: 0 Layout.column: 0
Layout.maximumWidth: 300 * theme.fontScale
} }
MyTextField { MyTextField {
id: gpuLayersField id: gpuLayersField