mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-06-27 07:48:19 +00:00
Fix bug with model loading on initial load.
This commit is contained in:
parent
3ca9e8692c
commit
64e98b8ea9
@ -17,6 +17,7 @@ Chat::Chat(QObject *parent)
|
|||||||
, m_isServer(false)
|
, m_isServer(false)
|
||||||
, m_shouldDeleteLater(false)
|
, m_shouldDeleteLater(false)
|
||||||
, m_isModelLoaded(false)
|
, m_isModelLoaded(false)
|
||||||
|
, m_shouldLoadModelWhenInstalled(false)
|
||||||
{
|
{
|
||||||
connectLLM();
|
connectLLM();
|
||||||
}
|
}
|
||||||
@ -33,6 +34,7 @@ Chat::Chat(bool isServer, QObject *parent)
|
|||||||
, m_isServer(true)
|
, m_isServer(true)
|
||||||
, m_shouldDeleteLater(false)
|
, m_shouldDeleteLater(false)
|
||||||
, m_isModelLoaded(false)
|
, m_isModelLoaded(false)
|
||||||
|
, m_shouldLoadModelWhenInstalled(false)
|
||||||
{
|
{
|
||||||
connectLLM();
|
connectLLM();
|
||||||
}
|
}
|
||||||
@ -65,6 +67,9 @@ void Chat::connectLLM()
|
|||||||
connect(this, &Chat::regenerateResponseRequested, m_llmodel, &ChatLLM::regenerateResponse, Qt::QueuedConnection);
|
connect(this, &Chat::regenerateResponseRequested, m_llmodel, &ChatLLM::regenerateResponse, Qt::QueuedConnection);
|
||||||
connect(this, &Chat::resetResponseRequested, m_llmodel, &ChatLLM::resetResponse, Qt::QueuedConnection);
|
connect(this, &Chat::resetResponseRequested, m_llmodel, &ChatLLM::resetResponse, Qt::QueuedConnection);
|
||||||
connect(this, &Chat::resetContextRequested, m_llmodel, &ChatLLM::resetContext, Qt::QueuedConnection);
|
connect(this, &Chat::resetContextRequested, m_llmodel, &ChatLLM::resetContext, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect(ModelList::globalInstance()->installedModels(), &InstalledModels::countChanged,
|
||||||
|
this, &Chat::handleModelInstalled, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chat::reset()
|
void Chat::reset()
|
||||||
@ -311,9 +316,23 @@ void Chat::unloadModel()
|
|||||||
|
|
||||||
void Chat::reloadModel()
|
void Chat::reloadModel()
|
||||||
{
|
{
|
||||||
|
// If the installed model list is empty, then we mark a special flag and monitor for when a model
|
||||||
|
// is installed
|
||||||
|
if (!ModelList::globalInstance()->installedModels()->count()) {
|
||||||
|
m_shouldLoadModelWhenInstalled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_llmodel->setShouldBeLoaded(true);
|
m_llmodel->setShouldBeLoaded(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chat::handleModelInstalled()
|
||||||
|
{
|
||||||
|
if (!m_shouldLoadModelWhenInstalled)
|
||||||
|
return;
|
||||||
|
m_shouldLoadModelWhenInstalled = false;
|
||||||
|
reloadModel();
|
||||||
|
}
|
||||||
|
|
||||||
void Chat::generatedNameChanged(const QString &name)
|
void Chat::generatedNameChanged(const QString &name)
|
||||||
{
|
{
|
||||||
// Only use the first three words maximum and remove newlines and extra spaces
|
// Only use the first three words maximum and remove newlines and extra spaces
|
||||||
|
@ -130,6 +130,7 @@ private Q_SLOTS:
|
|||||||
void handleTokenSpeedChanged(const QString &tokenSpeed);
|
void handleTokenSpeedChanged(const QString &tokenSpeed);
|
||||||
void handleDatabaseResultsChanged(const QList<ResultInfo> &results);
|
void handleDatabaseResultsChanged(const QList<ResultInfo> &results);
|
||||||
void handleModelInfoChanged(const ModelInfo &modelInfo);
|
void handleModelInfoChanged(const ModelInfo &modelInfo);
|
||||||
|
void handleModelInstalled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
@ -150,6 +151,7 @@ private:
|
|||||||
bool m_isServer;
|
bool m_isServer;
|
||||||
bool m_shouldDeleteLater;
|
bool m_shouldDeleteLater;
|
||||||
bool m_isModelLoaded;
|
bool m_isModelLoaded;
|
||||||
|
bool m_shouldLoadModelWhenInstalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHAT_H
|
#endif // CHAT_H
|
||||||
|
@ -513,7 +513,7 @@ void HashAndSaveFile::hashAndSave(const QString &expectedHash, const QString &sa
|
|||||||
} else {
|
} else {
|
||||||
QFile::FileError error = file.error();
|
QFile::FileError error = file.error();
|
||||||
const QString errorString
|
const QString errorString
|
||||||
= QString("ERROR: Could not save model to location: %1 failed with code %2").arg(saveFilePath).arg(error);
|
= QString("ERROR: Could not save model to location: %1 failed with code %1").arg(saveFilePath).arg(error);
|
||||||
qWarning() << errorString;
|
qWarning() << errorString;
|
||||||
tempFile->close();
|
tempFile->close();
|
||||||
emit hashAndSaveFinished(false, errorString, tempFile, modelReply);
|
emit hashAndSaveFinished(false, errorString, tempFile, modelReply);
|
||||||
@ -532,11 +532,13 @@ void Download::handleModelDownloadFinished()
|
|||||||
m_activeDownloads.remove(modelReply);
|
m_activeDownloads.remove(modelReply);
|
||||||
|
|
||||||
if (modelReply->error()) {
|
if (modelReply->error()) {
|
||||||
qWarning() << "ERROR: downloading:" << modelReply->errorString();
|
const QString errorString
|
||||||
|
= QString("ERROR: Downloading failed with code %1 \"%2\"").arg(modelReply->error()).arg(modelReply->errorString());
|
||||||
|
qWarning() << errorString;
|
||||||
modelReply->deleteLater();
|
modelReply->deleteLater();
|
||||||
tempFile->deleteLater();
|
tempFile->deleteLater();
|
||||||
ModelList::globalInstance()->updateData(modelFilename, ModelList::DownloadingRole, false);
|
ModelList::globalInstance()->updateData(modelFilename, ModelList::DownloadingRole, false);
|
||||||
ModelList::globalInstance()->updateData(modelFilename, ModelList::DownloadErrorRole, modelReply->errorString());
|
ModelList::globalInstance()->updateData(modelFilename, ModelList::DownloadErrorRole, errorString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +50,6 @@ Window {
|
|||||||
|
|
||||||
// Startup code
|
// Startup code
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!LLM.compatHardware) {
|
|
||||||
Network.sendNonCompatHardware();
|
|
||||||
errorCompatHardware.open();
|
|
||||||
} else
|
|
||||||
startupDialogs();
|
startupDialogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +87,12 @@ Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startupDialogs() {
|
function startupDialogs() {
|
||||||
|
if (!LLM.compatHardware) {
|
||||||
|
Network.sendNonCompatHardware();
|
||||||
|
errorCompatHardware.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check for first time start of this version
|
// check for first time start of this version
|
||||||
if (Download.isFirstStart()) {
|
if (Download.isFirstStart()) {
|
||||||
firstStartDialog.open();
|
firstStartDialog.open();
|
||||||
@ -98,7 +100,7 @@ Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for any current models and if not, open download dialog
|
// check for any current models and if not, open download dialog
|
||||||
if (ModelList.count === 0 && !firstStartDialog.opened) {
|
if (ModelList.installedModels.count === 0 && !firstStartDialog.opened) {
|
||||||
downloadNewModels.open();
|
downloadNewModels.open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -117,7 +119,14 @@ Window {
|
|||||||
shouldShowBusy: false
|
shouldShowBusy: false
|
||||||
closePolicy: Popup.NoAutoClose
|
closePolicy: Popup.NoAutoClose
|
||||||
modal: true
|
modal: true
|
||||||
text: qsTr("Incompatible hardware detected. Your hardware does not meet the minimal requirements to run GPT4All. In particular, it does not seem to support AVX intrinsics. See here for more: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions")
|
text: qsTr("<h3>Encountered an error starting up:</h3><br>")
|
||||||
|
+ qsTr("<i>\"Incompatible hardware detected.\"</i>")
|
||||||
|
+ qsTr("<br><br>Unfortunately, your CPU does not meet the minimal requirements to run ")
|
||||||
|
+ qsTr("this program. In particular, it does not support AVX intrinsics which this ")
|
||||||
|
+ qsTr("program requires to successfully run a modern large language model. ")
|
||||||
|
+ qsTr("The only solution at this time is to upgrade your hardware to a more modern CPU.")
|
||||||
|
+ qsTr("<br><br>See here for more information: ")
|
||||||
|
+ qsTr("https://en.wikipedia.org/wiki/Advanced_Vector_Extensions")
|
||||||
}
|
}
|
||||||
|
|
||||||
StartupDialog {
|
StartupDialog {
|
||||||
@ -205,9 +214,11 @@ Window {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
rightPadding: 20
|
rightPadding: 20
|
||||||
text: currentChat.modelLoadingError !== "" ? qsTr("Model loading error...")
|
text: ModelList.installedModels.count
|
||||||
|
? currentChat.modelLoadingError !== "" ? qsTr("Model loading error...")
|
||||||
: (comboBox.textAt(comboBox.currentIndex) !== "" ? comboBox.textAt(comboBox.currentIndex)
|
: (comboBox.textAt(comboBox.currentIndex) !== "" ? comboBox.textAt(comboBox.currentIndex)
|
||||||
: comboBox.valueAt(comboBox.currentIndex))
|
: comboBox.valueAt(comboBox.currentIndex))
|
||||||
|
: ""
|
||||||
font: comboBox.font
|
font: comboBox.font
|
||||||
color: theme.textColor
|
color: theme.textColor
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
@ -241,7 +252,10 @@ Window {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !currentChat.isModelLoaded && currentChat.modelLoadingError === "" && !currentChat.isServer
|
visible: ModelList.installedModels.count
|
||||||
|
&& !currentChat.isModelLoaded
|
||||||
|
&& currentChat.modelLoadingError === ""
|
||||||
|
&& !currentChat.isServer
|
||||||
width: childrenRect.width
|
width: childrenRect.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
Row {
|
Row {
|
||||||
|
@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
InstalledModels::InstalledModels(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
connect(this, &InstalledModels::rowsInserted, this, &InstalledModels::countChanged);
|
||||||
|
connect(this, &InstalledModels::rowsRemoved, this, &InstalledModels::countChanged);
|
||||||
|
connect(this, &InstalledModels::modelReset, this, &InstalledModels::countChanged);
|
||||||
|
connect(this, &InstalledModels::layoutChanged, this, &InstalledModels::countChanged);
|
||||||
|
}
|
||||||
|
|
||||||
bool InstalledModels::filterAcceptsRow(int sourceRow,
|
bool InstalledModels::filterAcceptsRow(int sourceRow,
|
||||||
const QModelIndex &sourceParent) const
|
const QModelIndex &sourceParent) const
|
||||||
{
|
{
|
||||||
@ -10,6 +19,11 @@ bool InstalledModels::filterAcceptsRow(int sourceRow,
|
|||||||
return isInstalled;
|
return isInstalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InstalledModels::count() const
|
||||||
|
{
|
||||||
|
return rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
DownloadableModels::DownloadableModels(QObject *parent)
|
DownloadableModels::DownloadableModels(QObject *parent)
|
||||||
: QSortFilterProxyModel(parent)
|
: QSortFilterProxyModel(parent)
|
||||||
, m_expanded(false)
|
, m_expanded(false)
|
||||||
|
@ -69,8 +69,13 @@ Q_DECLARE_METATYPE(ModelInfo)
|
|||||||
class InstalledModels : public QSortFilterProxyModel
|
class InstalledModels : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||||
public:
|
public:
|
||||||
explicit InstalledModels(QObject *parent) : QSortFilterProxyModel(parent) {}
|
explicit InstalledModels(QObject *parent);
|
||||||
|
int count() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
@ -146,13 +146,12 @@ model release that uses your data!")
|
|||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.row: 0
|
Layout.row: 0
|
||||||
Layout.column: 1
|
Layout.column: 1
|
||||||
property bool defaultChecked: Network.usageStatsActive
|
|
||||||
property alias checked: optInStatisticsRadioYes.checked
|
property alias checked: optInStatisticsRadioYes.checked
|
||||||
property bool choiceMade: optInStatisticsRadioYes.checked || optInStatisticsRadioNo.checked
|
property bool choiceMade: optInStatisticsRadioYes.checked || optInStatisticsRadioNo.checked
|
||||||
|
|
||||||
RadioButton {
|
RadioButton {
|
||||||
id: optInStatisticsRadioYes
|
id: optInStatisticsRadioYes
|
||||||
checked: optInStatisticsRadio.defaultChecked
|
checked: false
|
||||||
text: qsTr("Yes")
|
text: qsTr("Yes")
|
||||||
Accessible.role: Accessible.RadioButton
|
Accessible.role: Accessible.RadioButton
|
||||||
Accessible.name: qsTr("Opt-in for anonymous usage statistics")
|
Accessible.name: qsTr("Opt-in for anonymous usage statistics")
|
||||||
@ -258,13 +257,12 @@ model release that uses your data!")
|
|||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.row: 1
|
Layout.row: 1
|
||||||
Layout.column: 1
|
Layout.column: 1
|
||||||
property bool defaultChecked: Network.isActive
|
|
||||||
property alias checked: optInNetworkRadioYes.checked
|
property alias checked: optInNetworkRadioYes.checked
|
||||||
property bool choiceMade: optInNetworkRadioYes.checked || optInNetworkRadioNo.checked
|
property bool choiceMade: optInNetworkRadioYes.checked || optInNetworkRadioNo.checked
|
||||||
|
|
||||||
RadioButton {
|
RadioButton {
|
||||||
id: optInNetworkRadioYes
|
id: optInNetworkRadioYes
|
||||||
checked: optInNetworkRadio.defaultChecked
|
checked: false
|
||||||
text: qsTr("Yes")
|
text: qsTr("Yes")
|
||||||
Accessible.role: Accessible.RadioButton
|
Accessible.role: Accessible.RadioButton
|
||||||
Accessible.name: qsTr("Opt-in for network")
|
Accessible.name: qsTr("Opt-in for network")
|
||||||
|
Loading…
Reference in New Issue
Block a user