Batch all operations for updateData to avoid excessive sort.

Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
Adam Treat 2024-03-07 14:27:23 -05:00 committed by AT
parent 17dee02287
commit 08b5dc8598
3 changed files with 196 additions and 168 deletions

View File

@ -109,7 +109,9 @@ void Download::downloadModel(const QString &modelFile)
= QString("ERROR: Could not open temp file: %1 %2").arg(tempFile->fileName()).arg(modelFile); = QString("ERROR: Could not open temp file: %1 %2").arg(tempFile->fileName()).arg(modelFile);
qWarning() << error; qWarning() << error;
clearRetry(modelFile); clearRetry(modelFile);
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::DownloadErrorRole, error); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::DownloadErrorRole, error));
ModelList::globalInstance()->updateDataByFilename(modelFile, data);
return; return;
} }
tempFile->flush(); tempFile->flush();
@ -128,7 +130,9 @@ void Download::downloadModel(const QString &modelFile)
return; return;
} }
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::DownloadingRole, true); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::DownloadingRole, true));
ModelList::globalInstance()->updateDataByFilename(modelFile, data);
ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFile); ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFile);
QString url = !info.url().isEmpty() ? info.url() : "http://gpt4all.io/models/gguf/" + modelFile; QString url = !info.url().isEmpty() ? info.url() : "http://gpt4all.io/models/gguf/" + modelFile;
Network::globalInstance()->sendDownloadStarted(modelFile); Network::globalInstance()->sendDownloadStarted(modelFile);
@ -166,7 +170,9 @@ void Download::cancelDownload(const QString &modelFile)
tempFile->deleteLater(); tempFile->deleteLater();
m_activeDownloads.remove(modelReply); m_activeDownloads.remove(modelReply);
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::DownloadingRole, false); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::DownloadingRole, false));
ModelList::globalInstance()->updateDataByFilename(modelFile, data);
break; break;
} }
} }
@ -188,7 +194,9 @@ void Download::installModel(const QString &modelFile, const QString &apiKey)
ModelList::globalInstance()->updateModelsFromDirectory(); ModelList::globalInstance()->updateModelsFromDirectory();
} }
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::InstalledRole, true); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::InstalledRole, true));
ModelList::globalInstance()->updateDataByFilename(modelFile, data);
} }
void Download::removeModel(const QString &modelFile) void Download::removeModel(const QString &modelFile)
@ -199,20 +207,27 @@ void Download::removeModel(const QString &modelFile)
incompleteFile.remove(); incompleteFile.remove();
} }
bool shouldRemoveInstalled = false;
QFile file(filePath); QFile file(filePath);
if (file.exists()) { if (file.exists()) {
const ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFile); const ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFile);
ModelList::globalInstance()->removeInstalled(info); shouldRemoveInstalled = info.installed && !info.isClone() && (info.isDiscovered() || info.description() == "");
if (shouldRemoveInstalled)
ModelList::globalInstance()->removeInstalled(info);
Network::globalInstance()->sendRemoveModel(modelFile); Network::globalInstance()->sendRemoveModel(modelFile);
file.remove(); file.remove();
} }
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::InstalledRole, false); if (!shouldRemoveInstalled) {
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::BytesReceivedRole, 0); QVector<QPair<int, QVariant>> data;
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::BytesTotalRole, 0); data.append(qMakePair(ModelList::InstalledRole, false));
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::TimestampRole, 0); data.append(qMakePair(ModelList::BytesReceivedRole, 0));
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::SpeedRole, QString()); data.append(qMakePair(ModelList::BytesTotalRole, 0));
ModelList::globalInstance()->updateDataByFilename(modelFile, ModelList::DownloadErrorRole, QString()); data.append(qMakePair(ModelList::TimestampRole, 0));
data.append(qMakePair(ModelList::SpeedRole, QString()));
data.append(qMakePair(ModelList::DownloadErrorRole, QString()));
ModelList::globalInstance()->updateDataByFilename(modelFile, data);
}
} }
void Download::handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors) void Download::handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
@ -313,7 +328,9 @@ void Download::handleErrorOccurred(QNetworkReply::NetworkError code)
.arg(code) .arg(code)
.arg(modelReply->errorString()); .arg(modelReply->errorString());
qWarning() << error; qWarning() << error;
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadErrorRole, error); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::DownloadErrorRole, error));
ModelList::globalInstance()->updateDataByFilename(modelFilename, data);
Network::globalInstance()->sendDownloadError(modelFilename, (int)code, modelReply->errorString()); Network::globalInstance()->sendDownloadError(modelFilename, (int)code, modelReply->errorString());
cancelDownload(modelFilename); cancelDownload(modelFilename);
} }
@ -352,10 +369,12 @@ void Download::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
else else
speedText = QString::number(static_cast<double>(speed / (1024.0 * 1024.0)), 'f', 2) + " MB/s"; speedText = QString::number(static_cast<double>(speed / (1024.0 * 1024.0)), 'f', 2) + " MB/s";
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::BytesReceivedRole, currentBytesReceived); QVector<QPair<int, QVariant>> data;
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::BytesTotalRole, bytesTotal); data.append(qMakePair(ModelList::BytesReceivedRole, currentBytesReceived));
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::SpeedRole, speedText); data.append(qMakePair(ModelList::BytesTotalRole, bytesTotal));
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::TimestampRole, currentUpdate); data.append(qMakePair(ModelList::SpeedRole, speedText));
data.append(qMakePair(ModelList::TimestampRole, currentUpdate));
ModelList::globalInstance()->updateDataByFilename(modelFilename, data);
} }
HashAndSaveFile::HashAndSaveFile() HashAndSaveFile::HashAndSaveFile()
@ -457,8 +476,10 @@ void Download::handleModelDownloadFinished()
modelReply->deleteLater(); modelReply->deleteLater();
tempFile->deleteLater(); tempFile->deleteLater();
if (!hasRetry(modelFilename)) { if (!hasRetry(modelFilename)) {
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadingRole, false); QVector<QPair<int, QVariant>> data;
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadErrorRole, errorString); data.append(qMakePair(ModelList::DownloadingRole, false));
data.append(qMakePair(ModelList::DownloadErrorRole, errorString));
ModelList::globalInstance()->updateDataByFilename(modelFilename, data);
} }
return; return;
} }
@ -476,7 +497,9 @@ void Download::handleModelDownloadFinished()
} }
// Notify that we are calculating hash // Notify that we are calculating hash
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::CalcHashRole, true); QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::CalcHashRole, true));
ModelList::globalInstance()->updateDataByFilename(modelFilename, data);
QByteArray hash = ModelList::globalInstance()->modelInfoByFilename(modelFilename).hash; QByteArray hash = ModelList::globalInstance()->modelInfoByFilename(modelFilename).hash;
ModelInfo::HashAlgorithm hashAlgorithm = ModelList::globalInstance()->modelInfoByFilename(modelFilename).hashAlgorithm; ModelInfo::HashAlgorithm hashAlgorithm = ModelList::globalInstance()->modelInfoByFilename(modelFilename).hashAlgorithm;
const QString saveFilePath = MySettings::globalInstance()->modelPath() + modelFilename; const QString saveFilePath = MySettings::globalInstance()->modelPath() + modelFilename;
@ -492,19 +515,24 @@ void Download::handleHashAndSaveFinished(bool success, const QString &error,
Q_ASSERT(!tempFile->isOpen()); Q_ASSERT(!tempFile->isOpen());
QString modelFilename = modelReply->request().attribute(QNetworkRequest::User).toString(); QString modelFilename = modelReply->request().attribute(QNetworkRequest::User).toString();
Network::globalInstance()->sendDownloadFinished(modelFilename, success); Network::globalInstance()->sendDownloadFinished(modelFilename, success);
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::CalcHashRole, false);
QVector<QPair<int, QVariant>> data;
data.append(qMakePair(ModelList::CalcHashRole, false));
data.append(qMakePair(ModelList::DownloadingRole, false));
modelReply->deleteLater(); modelReply->deleteLater();
tempFile->deleteLater(); tempFile->deleteLater();
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadingRole, false);
if (!success) { if (!success) {
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadErrorRole, error); data.append(qMakePair(ModelList::DownloadErrorRole, error));
} else { } else {
data.append(qMakePair(ModelList::DownloadErrorRole, QString()));
ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFilename); ModelInfo info = ModelList::globalInstance()->modelInfoByFilename(modelFilename);
if (info.isDiscovered()) if (info.isDiscovered())
ModelList::globalInstance()->updateDiscoveredInstalled(info); ModelList::globalInstance()->updateDiscoveredInstalled(info);
ModelList::globalInstance()->updateDataByFilename(modelFilename, ModelList::DownloadErrorRole, QString());
} }
ModelList::globalInstance()->updateDataByFilename(modelFilename, data);
} }
void Download::handleReadyRead() void Download::handleReadyRead()

View File

@ -785,13 +785,6 @@ QVariant ModelList::data(const QModelIndex &index, int role) const
return dataInternal(info, role); return dataInternal(info, role);
} }
void ModelList::updateData(const QString &id, int role, const QVariant &value)
{
QVector<QPair<int, QVariant>> data;
data.append(qMakePair(role, value));
updateData(id, data);
}
void ModelList::updateData(const QString &id, const QVector<QPair<int, QVariant>> &data) void ModelList::updateData(const QString &id, const QVector<QPair<int, QVariant>> &data)
{ {
int index; int index;
@ -936,7 +929,7 @@ void ModelList::resortModel()
emit layoutChanged(); emit layoutChanged();
} }
void ModelList::updateDataByFilename(const QString &filename, int role, const QVariant &value) void ModelList::updateDataByFilename(const QString &filename, const QVector<QPair<int, QVariant>> &data)
{ {
QVector<QString> modelsById; QVector<QString> modelsById;
{ {
@ -952,7 +945,7 @@ void ModelList::updateDataByFilename(const QString &filename, int role, const QV
} }
for (const QString &id : modelsById) for (const QString &id : modelsById)
updateData(id, role, value);; updateData(id, data);
} }
ModelInfo ModelList::modelInfo(const QString &id) const ModelInfo ModelList::modelInfo(const QString &id) const
@ -986,24 +979,27 @@ QString ModelList::clone(const ModelInfo &model)
{ {
const QString id = Network::globalInstance()->generateUniqueId(); const QString id = Network::globalInstance()->generateUniqueId();
addModel(id); addModel(id);
updateData(id, ModelList::IsCloneRole, true);
updateData(id, ModelList::NameRole, uniqueModelName(model)); QVector<QPair<int, QVariant>> data;
updateData(id, ModelList::FilenameRole, model.filename()); data.append(qMakePair(ModelList::InstalledRole, model.installed));
updateData(id, ModelList::DirpathRole, model.dirpath); data.append(qMakePair(ModelList::IsCloneRole, true));
updateData(id, ModelList::InstalledRole, model.installed); data.append(qMakePair(ModelList::NameRole, uniqueModelName(model)));
updateData(id, ModelList::OnlineRole, model.isOnline); data.append(qMakePair(ModelList::FilenameRole, model.filename()));
updateData(id, ModelList::TemperatureRole, model.temperature()); data.append(qMakePair(ModelList::DirpathRole, model.dirpath));
updateData(id, ModelList::TopPRole, model.topP()); data.append(qMakePair(ModelList::OnlineRole, model.isOnline));
updateData(id, ModelList::MinPRole, model.minP()); data.append(qMakePair(ModelList::TemperatureRole, model.temperature()));
updateData(id, ModelList::TopKRole, model.topK()); data.append(qMakePair(ModelList::TopPRole, model.topP()));
updateData(id, ModelList::MaxLengthRole, model.maxLength()); data.append(qMakePair(ModelList::MinPRole, model.minP()));
updateData(id, ModelList::PromptBatchSizeRole, model.promptBatchSize()); data.append(qMakePair(ModelList::TopKRole, model.topK()));
updateData(id, ModelList::ContextLengthRole, model.contextLength()); data.append(qMakePair(ModelList::MaxLengthRole, model.maxLength()));
updateData(id, ModelList::GpuLayersRole, model.gpuLayers()); data.append(qMakePair(ModelList::PromptBatchSizeRole, model.promptBatchSize()));
updateData(id, ModelList::RepeatPenaltyRole, model.repeatPenalty()); data.append(qMakePair(ModelList::ContextLengthRole, model.contextLength()));
updateData(id, ModelList::RepeatPenaltyTokensRole, model.repeatPenaltyTokens()); data.append(qMakePair(ModelList::GpuLayersRole, model.gpuLayers()));
updateData(id, ModelList::PromptTemplateRole, model.promptTemplate()); data.append(qMakePair(ModelList::RepeatPenaltyRole, model.repeatPenalty()));
updateData(id, ModelList::SystemPromptRole, model.systemPrompt()); data.append(qMakePair(ModelList::RepeatPenaltyTokensRole, model.repeatPenaltyTokens()));
data.append(qMakePair(ModelList::PromptTemplateRole, model.promptTemplate()));
data.append(qMakePair(ModelList::SystemPromptRole, model.systemPrompt()));
updateData(id, data);
return id; return id;
} }
@ -1019,18 +1015,9 @@ void ModelList::removeClone(const ModelInfo &model)
void ModelList::removeInstalled(const ModelInfo &model) void ModelList::removeInstalled(const ModelInfo &model)
{ {
// We only remove a model if it is installed and is discovered or sideloaded Q_ASSERT(model.installed);
if (!model.installed || !(model.isDiscovered() || model.description() == "" /*indicates sideloaded*/)) Q_ASSERT(!model.isClone());
return; Q_ASSERT(model.isDiscovered() || model.description() == "" /*indicates sideloaded*/);
// We shouldn't remove it if a discovered search is in progress or completed because the
// clearing of that search will erase it...
// FIXME: This won't be true in a bit when save the installed portion to settings, then we'll need to
// use this... or at least unflag the installed bit...
if (m_discoverNumberOfResults)
return;
removeInternal(model); removeInternal(model);
emit layoutChanged(); emit layoutChanged();
} }
@ -1156,12 +1143,14 @@ void ModelList::updateModelsFromDirectory()
} }
for (const QString &id : modelsById) { for (const QString &id : modelsById) {
updateData(id, InstalledRole, true); QVector<QPair<int, QVariant>> data;
updateData(id, FilenameRole, filename); data.append(qMakePair(InstalledRole, true));
data.append(qMakePair(FilenameRole, filename));
// FIXME: WE should change this to use a consistent filename for online models // FIXME: WE should change this to use a consistent filename for online models
updateData(id, OnlineRole, filename.startsWith("chatgpt-") || filename.startsWith("nomic-")); data.append(qMakePair(OnlineRole, filename.startsWith("chatgpt-") || filename.startsWith("nomic-")));
updateData(id, DirpathRole, info.dir().absolutePath() + "/"); data.append(qMakePair(DirpathRole, info.dir().absolutePath() + "/"));
updateData(id, FilesizeRole, toFileSize(info.size())); data.append(qMakePair(FilesizeRole, toFileSize(info.size())));
updateData(id, data);
} }
} }
} }
@ -1359,46 +1348,48 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
if (!contains(id)) if (!contains(id))
addModel(id); addModel(id);
updateData(id, ModelList::NameRole, modelName); QVector<QPair<int, QVariant>> data;
updateData(id, ModelList::FilenameRole, modelFilename); data.append(qMakePair(ModelList::NameRole, modelName));
updateData(id, ModelList::FilesizeRole, modelFilesize); data.append(qMakePair(ModelList::FilenameRole, modelFilename));
updateData(id, ModelList::HashRole, modelHash); data.append(qMakePair(ModelList::FilesizeRole, modelFilesize));
updateData(id, ModelList::HashAlgorithmRole, ModelInfo::Md5); data.append(qMakePair(ModelList::HashRole, modelHash));
updateData(id, ModelList::DefaultRole, isDefault); data.append(qMakePair(ModelList::HashAlgorithmRole, ModelInfo::Md5));
updateData(id, ModelList::DescriptionRole, description); data.append(qMakePair(ModelList::DefaultRole, isDefault));
updateData(id, ModelList::RequiresVersionRole, requiresVersion); data.append(qMakePair(ModelList::DescriptionRole, description));
updateData(id, ModelList::VersionRemovedRole, versionRemoved); data.append(qMakePair(ModelList::RequiresVersionRole, requiresVersion));
updateData(id, ModelList::UrlRole, url); data.append(qMakePair(ModelList::VersionRemovedRole, versionRemoved));
updateData(id, ModelList::DisableGUIRole, disableGUI); data.append(qMakePair(ModelList::UrlRole, url));
updateData(id, ModelList::OrderRole, order); data.append(qMakePair(ModelList::DisableGUIRole, disableGUI));
updateData(id, ModelList::RamrequiredRole, ramrequired); data.append(qMakePair(ModelList::OrderRole, order));
updateData(id, ModelList::ParametersRole, parameters); data.append(qMakePair(ModelList::RamrequiredRole, ramrequired));
updateData(id, ModelList::QuantRole, quant); data.append(qMakePair(ModelList::ParametersRole, parameters));
updateData(id, ModelList::TypeRole, type); data.append(qMakePair(ModelList::QuantRole, quant));
data.append(qMakePair(ModelList::TypeRole, type));
if (obj.contains("temperature")) if (obj.contains("temperature"))
updateData(id, ModelList::TemperatureRole, obj["temperature"].toDouble()); data.append(qMakePair(ModelList::TemperatureRole, obj["temperature"].toDouble()));
if (obj.contains("topP")) if (obj.contains("topP"))
updateData(id, ModelList::TopPRole, obj["topP"].toDouble()); data.append(qMakePair(ModelList::TopPRole, obj["topP"].toDouble()));
if (obj.contains("minP")) if (obj.contains("minP"))
updateData(id, ModelList::MinPRole, obj["minP"].toDouble()); data.append(qMakePair(ModelList::MinPRole, obj["minP"].toDouble()));
if (obj.contains("topK")) if (obj.contains("topK"))
updateData(id, ModelList::TopKRole, obj["topK"].toInt()); data.append(qMakePair(ModelList::TopKRole, obj["topK"].toInt()));
if (obj.contains("maxLength")) if (obj.contains("maxLength"))
updateData(id, ModelList::MaxLengthRole, obj["maxLength"].toInt()); data.append(qMakePair(ModelList::MaxLengthRole, obj["maxLength"].toInt()));
if (obj.contains("promptBatchSize")) if (obj.contains("promptBatchSize"))
updateData(id, ModelList::PromptBatchSizeRole, obj["promptBatchSize"].toInt()); data.append(qMakePair(ModelList::PromptBatchSizeRole, obj["promptBatchSize"].toInt()));
if (obj.contains("contextLength")) if (obj.contains("contextLength"))
updateData(id, ModelList::ContextLengthRole, obj["contextLength"].toInt()); data.append(qMakePair(ModelList::ContextLengthRole, obj["contextLength"].toInt()));
if (obj.contains("gpuLayers")) if (obj.contains("gpuLayers"))
updateData(id, ModelList::GpuLayersRole, obj["gpuLayers"].toInt()); data.append(qMakePair(ModelList::GpuLayersRole, obj["gpuLayers"].toInt()));
if (obj.contains("repeatPenalty")) if (obj.contains("repeatPenalty"))
updateData(id, ModelList::RepeatPenaltyRole, obj["repeatPenalty"].toDouble()); data.append(qMakePair(ModelList::RepeatPenaltyRole, obj["repeatPenalty"].toDouble()));
if (obj.contains("repeatPenaltyTokens")) if (obj.contains("repeatPenaltyTokens"))
updateData(id, ModelList::RepeatPenaltyTokensRole, obj["repeatPenaltyTokens"].toInt()); data.append(qMakePair(ModelList::RepeatPenaltyTokensRole, obj["repeatPenaltyTokens"].toInt()));
if (obj.contains("promptTemplate")) if (obj.contains("promptTemplate"))
updateData(id, ModelList::PromptTemplateRole, obj["promptTemplate"].toString()); data.append(qMakePair(ModelList::PromptTemplateRole, obj["promptTemplate"].toString()));
if (obj.contains("systemPrompt")) if (obj.contains("systemPrompt"))
updateData(id, ModelList::SystemPromptRole, obj["systemPrompt"].toString()); data.append(qMakePair(ModelList::SystemPromptRole, obj["systemPrompt"].toString()));
updateData(id, data);
} }
const QString chatGPTDesc = tr("<ul><li>Requires personal OpenAI API key.</li><li>WARNING: Will send" const QString chatGPTDesc = tr("<ul><li>Requires personal OpenAI API key.</li><li>WARNING: Will send"
@ -1414,18 +1405,20 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
changeId(modelFilename, id); changeId(modelFilename, id);
if (!contains(id)) if (!contains(id))
addModel(id); addModel(id);
updateData(id, ModelList::NameRole, modelName); QVector<QPair<int, QVariant>> data;
updateData(id, ModelList::FilenameRole, modelFilename); data.append(qMakePair(ModelList::NameRole, modelName));
updateData(id, ModelList::FilesizeRole, "minimal"); data.append(qMakePair(ModelList::FilenameRole, modelFilename));
updateData(id, ModelList::OnlineRole, true); data.append(qMakePair(ModelList::FilesizeRole, "minimal"));
updateData(id, ModelList::DescriptionRole, data.append(qMakePair(ModelList::OnlineRole, true));
tr("<strong>OpenAI's ChatGPT model GPT-3.5 Turbo</strong><br>") + chatGPTDesc); data.append(qMakePair(ModelList::DescriptionRole,
updateData(id, ModelList::RequiresVersionRole, "2.4.2"); tr("<strong>OpenAI's ChatGPT model GPT-3.5 Turbo</strong><br>") + chatGPTDesc));
updateData(id, ModelList::OrderRole, "ca"); data.append(qMakePair(ModelList::RequiresVersionRole, "2.4.2"));
updateData(id, ModelList::RamrequiredRole, 0); data.append(qMakePair(ModelList::OrderRole, "ca"));
updateData(id, ModelList::ParametersRole, "?"); data.append(qMakePair(ModelList::RamrequiredRole, 0));
updateData(id, ModelList::QuantRole, "NA"); data.append(qMakePair(ModelList::ParametersRole, "?"));
updateData(id, ModelList::TypeRole, "GPT"); data.append(qMakePair(ModelList::QuantRole, "NA"));
data.append(qMakePair(ModelList::TypeRole, "GPT"));
updateData(id, data);
} }
{ {
@ -1438,18 +1431,20 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
changeId(modelFilename, id); changeId(modelFilename, id);
if (!contains(id)) if (!contains(id))
addModel(id); addModel(id);
updateData(id, ModelList::NameRole, modelName); QVector<QPair<int, QVariant>> data;
updateData(id, ModelList::FilenameRole, modelFilename); data.append(qMakePair(ModelList::NameRole, modelName));
updateData(id, ModelList::FilesizeRole, "minimal"); data.append(qMakePair(ModelList::FilenameRole, modelFilename));
updateData(id, ModelList::OnlineRole, true); data.append(qMakePair(ModelList::FilesizeRole, "minimal"));
updateData(id, ModelList::DescriptionRole, data.append(qMakePair(ModelList::OnlineRole, true));
tr("<strong>OpenAI's ChatGPT model GPT-4</strong><br>") + chatGPTDesc + chatGPT4Warn); data.append(qMakePair(ModelList::DescriptionRole,
updateData(id, ModelList::RequiresVersionRole, "2.4.2"); tr("<strong>OpenAI's ChatGPT model GPT-4</strong><br>") + chatGPTDesc + chatGPT4Warn));
updateData(id, ModelList::OrderRole, "cb"); data.append(qMakePair(ModelList::RequiresVersionRole, "2.4.2"));
updateData(id, ModelList::RamrequiredRole, 0); data.append(qMakePair(ModelList::OrderRole, "cb"));
updateData(id, ModelList::ParametersRole, "?"); data.append(qMakePair(ModelList::RamrequiredRole, 0));
updateData(id, ModelList::QuantRole, "NA"); data.append(qMakePair(ModelList::ParametersRole, "?"));
updateData(id, ModelList::TypeRole, "GPT"); data.append(qMakePair(ModelList::QuantRole, "NA"));
data.append(qMakePair(ModelList::TypeRole, "GPT"));
updateData(id, data);
} }
{ {
@ -1465,35 +1460,39 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
changeId(modelFilename, id); changeId(modelFilename, id);
if (!contains(id)) if (!contains(id))
addModel(id); addModel(id);
updateData(id, ModelList::NameRole, modelName); QVector<QPair<int, QVariant>> data;
updateData(id, ModelList::FilenameRole, modelFilename); data.append(qMakePair(ModelList::NameRole, modelName));
updateData(id, ModelList::FilesizeRole, "minimal"); data.append(qMakePair(ModelList::FilenameRole, modelFilename));
updateData(id, ModelList::OnlineRole, true); data.append(qMakePair(ModelList::FilesizeRole, "minimal"));
updateData(id, ModelList::DisableGUIRole, true); data.append(qMakePair(ModelList::OnlineRole, true));
updateData(id, ModelList::DescriptionRole, data.append(qMakePair(ModelList::DisableGUIRole, true));
tr("<strong>LocalDocs Nomic Atlas Embed</strong><br>") + nomicEmbedDesc); data.append(qMakePair(ModelList::DescriptionRole,
updateData(id, ModelList::RequiresVersionRole, "2.6.3"); tr("<strong>LocalDocs Nomic Atlas Embed</strong><br>") + nomicEmbedDesc));
updateData(id, ModelList::OrderRole, "na"); data.append(qMakePair(ModelList::RequiresVersionRole, "2.6.3"));
updateData(id, ModelList::RamrequiredRole, 0); data.append(qMakePair(ModelList::OrderRole, "na"));
updateData(id, ModelList::ParametersRole, "?"); data.append(qMakePair(ModelList::RamrequiredRole, 0));
updateData(id, ModelList::QuantRole, "NA"); data.append(qMakePair(ModelList::ParametersRole, "?"));
updateData(id, ModelList::TypeRole, "Bert"); data.append(qMakePair(ModelList::QuantRole, "NA"));
data.append(qMakePair(ModelList::TypeRole, "Bert"));
updateData(id, data);
} }
} }
void ModelList::updateDiscoveredInstalled(const ModelInfo &info) void ModelList::updateDiscoveredInstalled(const ModelInfo &info)
{ {
updateData(info.id(), ModelList::InstalledRole, true); QVector<QPair<int, QVariant>> data;
updateData(info.id(), ModelList::IsDiscoveredRole, true); data.append(qMakePair(ModelList::InstalledRole, true));
updateData(info.id(), ModelList::NameRole, info.name()); data.append(qMakePair(ModelList::IsDiscoveredRole, true));
updateData(info.id(), ModelList::FilenameRole, info.filename()); data.append(qMakePair(ModelList::NameRole, info.name()));
updateData(info.id(), ModelList::DescriptionRole, info.description()); data.append(qMakePair(ModelList::FilenameRole, info.filename()));
updateData(info.id(), ModelList::UrlRole, info.url()); data.append(qMakePair(ModelList::DescriptionRole, info.description()));
updateData(info.id(), ModelList::LikesRole, info.likes()); data.append(qMakePair(ModelList::UrlRole, info.url()));
updateData(info.id(), ModelList::DownloadsRole, info.downloads()); data.append(qMakePair(ModelList::LikesRole, info.likes()));
updateData(info.id(), ModelList::RecencyRole, info.recency()); data.append(qMakePair(ModelList::DownloadsRole, info.downloads()));
updateData(info.id(), ModelList::QuantRole, info.quant()); data.append(qMakePair(ModelList::RecencyRole, info.recency()));
updateData(info.id(), ModelList::TypeRole, info.type()); data.append(qMakePair(ModelList::QuantRole, info.quant()));
data.append(qMakePair(ModelList::TypeRole, info.type()));
updateData(info.id(), data);
} }
void ModelList::updateModelsFromSettings() void ModelList::updateModelsFromSettings()
@ -1511,98 +1510,100 @@ void ModelList::updateModelsFromSettings()
addModel(id); addModel(id);
QVector<QPair<int, QVariant>> data;
if (settings.contains(g + "/name")) { if (settings.contains(g + "/name")) {
const QString name = settings.value(g + "/name").toString(); const QString name = settings.value(g + "/name").toString();
updateData(id, ModelList::NameRole, name); data.append(qMakePair(ModelList::NameRole, name));
} }
if (settings.contains(g + "/filename")) { if (settings.contains(g + "/filename")) {
const QString filename = settings.value(g + "/filename").toString(); const QString filename = settings.value(g + "/filename").toString();
updateData(id, ModelList::FilenameRole, filename); data.append(qMakePair(ModelList::FilenameRole, filename));
} }
if (settings.contains(g + "/description")) { if (settings.contains(g + "/description")) {
const QString d = settings.value(g + "/description").toString(); const QString d = settings.value(g + "/description").toString();
updateData(id, ModelList::DescriptionRole, d); data.append(qMakePair(ModelList::DescriptionRole, d));
} }
if (settings.contains(g + "/url")) { if (settings.contains(g + "/url")) {
const QString u = settings.value(g + "/url").toString(); const QString u = settings.value(g + "/url").toString();
updateData(id, ModelList::UrlRole, u); data.append(qMakePair(ModelList::UrlRole, u));
} }
if (settings.contains(g + "/quant")) { if (settings.contains(g + "/quant")) {
const QString q = settings.value(g + "/quant").toString(); const QString q = settings.value(g + "/quant").toString();
updateData(id, ModelList::QuantRole, q); data.append(qMakePair(ModelList::QuantRole, q));
} }
if (settings.contains(g + "/type")) { if (settings.contains(g + "/type")) {
const QString t = settings.value(g + "/type").toString(); const QString t = settings.value(g + "/type").toString();
updateData(id, ModelList::TypeRole, t); data.append(qMakePair(ModelList::TypeRole, t));
} }
if (settings.contains(g + "/isClone")) { if (settings.contains(g + "/isClone")) {
const bool b = settings.value(g + "/isClone").toBool(); const bool b = settings.value(g + "/isClone").toBool();
updateData(id, ModelList::IsCloneRole, b); data.append(qMakePair(ModelList::IsCloneRole, b));
} }
if (settings.contains(g + "/isDiscovered")) { if (settings.contains(g + "/isDiscovered")) {
const bool b = settings.value(g + "/isDiscovered").toBool(); const bool b = settings.value(g + "/isDiscovered").toBool();
updateData(id, ModelList::IsDiscoveredRole, b); data.append(qMakePair(ModelList::IsDiscoveredRole, b));
} }
if (settings.contains(g + "/likes")) { if (settings.contains(g + "/likes")) {
const int l = settings.value(g + "/likes").toInt(); const int l = settings.value(g + "/likes").toInt();
updateData(id, ModelList::LikesRole, l); data.append(qMakePair(ModelList::LikesRole, l));
} }
if (settings.contains(g + "/downloads")) { if (settings.contains(g + "/downloads")) {
const int d = settings.value(g + "/downloads").toInt(); const int d = settings.value(g + "/downloads").toInt();
updateData(id, ModelList::DownloadsRole, d); data.append(qMakePair(ModelList::DownloadsRole, d));
} }
if (settings.contains(g + "/recency")) { if (settings.contains(g + "/recency")) {
const QDateTime r = settings.value(g + "/recency").toDateTime(); const QDateTime r = settings.value(g + "/recency").toDateTime();
updateData(id, ModelList::RecencyRole, r); data.append(qMakePair(ModelList::RecencyRole, r));
} }
if (settings.contains(g + "/temperature")) { if (settings.contains(g + "/temperature")) {
const double temperature = settings.value(g + "/temperature").toDouble(); const double temperature = settings.value(g + "/temperature").toDouble();
updateData(id, ModelList::TemperatureRole, temperature); data.append(qMakePair(ModelList::TemperatureRole, temperature));
} }
if (settings.contains(g + "/topP")) { if (settings.contains(g + "/topP")) {
const double topP = settings.value(g + "/topP").toDouble(); const double topP = settings.value(g + "/topP").toDouble();
updateData(id, ModelList::TopPRole, topP); data.append(qMakePair(ModelList::TopPRole, topP));
} }
if (settings.contains(g + "/minP")) { if (settings.contains(g + "/minP")) {
const double minP = settings.value(g + "/minP").toDouble(); const double minP = settings.value(g + "/minP").toDouble();
updateData(id, ModelList::MinPRole, minP); data.append(qMakePair(ModelList::MinPRole, minP));
} }
if (settings.contains(g + "/topK")) { if (settings.contains(g + "/topK")) {
const int topK = settings.value(g + "/topK").toInt(); const int topK = settings.value(g + "/topK").toInt();
updateData(id, ModelList::TopKRole, topK); data.append(qMakePair(ModelList::TopKRole, topK));
} }
if (settings.contains(g + "/maxLength")) { if (settings.contains(g + "/maxLength")) {
const int maxLength = settings.value(g + "/maxLength").toInt(); const int maxLength = settings.value(g + "/maxLength").toInt();
updateData(id, ModelList::MaxLengthRole, maxLength); data.append(qMakePair(ModelList::MaxLengthRole, maxLength));
} }
if (settings.contains(g + "/promptBatchSize")) { if (settings.contains(g + "/promptBatchSize")) {
const int promptBatchSize = settings.value(g + "/promptBatchSize").toInt(); const int promptBatchSize = settings.value(g + "/promptBatchSize").toInt();
updateData(id, ModelList::PromptBatchSizeRole, promptBatchSize); data.append(qMakePair(ModelList::PromptBatchSizeRole, promptBatchSize));
} }
if (settings.contains(g + "/contextLength")) { if (settings.contains(g + "/contextLength")) {
const int contextLength = settings.value(g + "/contextLength").toInt(); const int contextLength = settings.value(g + "/contextLength").toInt();
updateData(id, ModelList::ContextLengthRole, contextLength); data.append(qMakePair(ModelList::ContextLengthRole, contextLength));
} }
if (settings.contains(g + "/gpuLayers")) { if (settings.contains(g + "/gpuLayers")) {
const int gpuLayers = settings.value(g + "/gpuLayers").toInt(); const int gpuLayers = settings.value(g + "/gpuLayers").toInt();
updateData(id, ModelList::GpuLayersRole, gpuLayers); data.append(qMakePair(ModelList::GpuLayersRole, gpuLayers));
} }
if (settings.contains(g + "/repeatPenalty")) { if (settings.contains(g + "/repeatPenalty")) {
const double repeatPenalty = settings.value(g + "/repeatPenalty").toDouble(); const double repeatPenalty = settings.value(g + "/repeatPenalty").toDouble();
updateData(id, ModelList::RepeatPenaltyRole, repeatPenalty); data.append(qMakePair(ModelList::RepeatPenaltyRole, repeatPenalty));
} }
if (settings.contains(g + "/repeatPenaltyTokens")) { if (settings.contains(g + "/repeatPenaltyTokens")) {
const int repeatPenaltyTokens = settings.value(g + "/repeatPenaltyTokens").toInt(); const int repeatPenaltyTokens = settings.value(g + "/repeatPenaltyTokens").toInt();
updateData(id, ModelList::RepeatPenaltyTokensRole, repeatPenaltyTokens); data.append(qMakePair(ModelList::RepeatPenaltyTokensRole, repeatPenaltyTokens));
} }
if (settings.contains(g + "/promptTemplate")) { if (settings.contains(g + "/promptTemplate")) {
const QString promptTemplate = settings.value(g + "/promptTemplate").toString(); const QString promptTemplate = settings.value(g + "/promptTemplate").toString();
updateData(id, ModelList::PromptTemplateRole, promptTemplate); data.append(qMakePair(ModelList::PromptTemplateRole, promptTemplate));
} }
if (settings.contains(g + "/systemPrompt")) { if (settings.contains(g + "/systemPrompt")) {
const QString systemPrompt = settings.value(g + "/systemPrompt").toString(); const QString systemPrompt = settings.value(g + "/systemPrompt").toString();
updateData(id, ModelList::SystemPromptRole, systemPrompt); data.append(qMakePair(ModelList::SystemPromptRole, systemPrompt));
} }
updateData(id, data);
} }
} }

View File

@ -373,8 +373,7 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QVariant data(const QString &id, int role) const; QVariant data(const QString &id, int role) const;
QVariant dataByFilename(const QString &filename, int role) const; QVariant dataByFilename(const QString &filename, int role) const;
void updateData(const QString &id, int role, const QVariant &value); void updateDataByFilename(const QString &filename, const QVector<QPair<int, QVariant>> &data);
void updateDataByFilename(const QString &filename, int role, const QVariant &value);
void updateData(const QString &id, const QVector<QPair<int, QVariant>> &data); void updateData(const QString &id, const QVector<QPair<int, QVariant>> &data);
int count() const { return m_models.size(); } int count() const { return m_models.size(); }