diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4257891..63f7a3f 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,6 +7,7 @@ "args": [ "-fdiagnostics-color=always", "-g", + "-fopenmp", "${fileDirname}/main.cpp", "${fileDirname}/Xenith/core.cpp", "${fileDirname}/Xenith/token/token.cpp", diff --git a/Xenith/core.cpp b/Xenith/core.cpp index 7d198e6..4ff2a76 100644 --- a/Xenith/core.cpp +++ b/Xenith/core.cpp @@ -1,6 +1,9 @@ -#include "core.h" +#include "core.hpp" #include #include +#include + +#define MAX_CORES 16 NeuralNetwork::NeuralNetwork(LayerStructure_t layers[], int count) : numLayers(count) { for (int i = 0; i < count; i++) sizes.push_back(layers[i].size); @@ -39,29 +42,42 @@ std::vector NeuralNetwork::feedForward(const std::vector& input) double NeuralNetwork::train(const std::vector& input, const std::vector& target, double lr) { - std::vector pred = feedForward(input); + omp_set_num_threads(MAX_CORES); + std::vector pred = feedForward(input); std::vector> errors(numLayers); errors[numLayers - 1].resize(sizes[numLayers - 1]); - + double totalErr = 0; - for (int i = 0; i < sizes[numLayers-1]; i++) { + + for (int i = 0; i < sizes[numLayers - 1]; i++) { double e = target[i] - pred[i]; - errors[numLayers-1][i] = e * pred[i] * (1.0 - pred[i]); + errors[numLayers - 1][i] = e * pred[i] * (1.0 - pred[i]); totalErr += e * e; } + for (int i = numLayers - 2; i > 0; i--) { errors[i].resize(sizes[i]); + + #pragma omp parallel for for (int j = 0; j < sizes[i]; j++) { double e = 0; - for (int k = 0; k < sizes[i+1]; k++) e += errors[i+1][k] * weights[i][k][j]; + for (int k = 0; k < sizes[i + 1]; k++) { + e += errors[i + 1][k] * weights[i][k][j]; + } errors[i][j] = e * outputs[i][j] * (1.0 - outputs[i][j]); } } for (int i = 0; i < numLayers - 1; i++) { - for (int j = 0; j < sizes[i+1]; j++) { - for (int k = 0; k < sizes[i]; k++) weights[i][j][k] += lr * errors[i+1][j] * outputs[i][k]; - biases[i][j] += lr * errors[i+1][j]; + #pragma omp parallel for + for (int j = 0; j < sizes[i + 1]; j++) { + double errorTerm = lr * errors[i + 1][j]; + + // Вложенный цикл обновления весов + for (int k = 0; k < sizes[i]; k++) { + weights[i][j][k] += errorTerm * outputs[i][k]; + } + biases[i][j] += errorTerm; } } diff --git a/Xenith/core.h b/Xenith/core.hpp similarity index 96% rename from Xenith/core.h rename to Xenith/core.hpp index dc79cd6..67e552e 100644 --- a/Xenith/core.h +++ b/Xenith/core.hpp @@ -1,7 +1,7 @@ #ifndef CORE_H #define CORE_H -#include "typedef.h" +#include "typedef.hpp" #include #include diff --git a/Xenith/shader.comp b/Xenith/shader.comp new file mode 100644 index 0000000..e288648 --- /dev/null +++ b/Xenith/shader.comp @@ -0,0 +1,2 @@ +#version 450 + diff --git a/Xenith/token/token.cpp b/Xenith/token/token.cpp index fa24bd7..4854973 100644 --- a/Xenith/token/token.cpp +++ b/Xenith/token/token.cpp @@ -1,4 +1,4 @@ -#include "token.h" +#include "token.hpp" #include #include diff --git a/Xenith/token/token.h b/Xenith/token/token.hpp similarity index 100% rename from Xenith/token/token.h rename to Xenith/token/token.hpp diff --git a/Xenith/typedef.h b/Xenith/typedef.hpp similarity index 62% rename from Xenith/typedef.h rename to Xenith/typedef.hpp index fcb6083..c22c150 100644 --- a/Xenith/typedef.h +++ b/Xenith/typedef.hpp @@ -1,8 +1,8 @@ #ifndef TYPEDEF_H #define TYPEDEF_H -const int MAX_CONTEXT = 8; // Сколько токенов видит сеть -const int EMBED_DIM = 4; // Размер вектора одного токена +const int MAX_CONTEXT = 32; // Сколько токенов видит сеть +const int EMBED_DIM = 8; // Размер вектора одного токена const int MAX_VOCAB = 90; // Размер словаря typedef enum { SIGMOID } FunctionActivate_t; diff --git a/dataset.txt b/dataset.txt index b9d0172..1e580e4 100644 --- a/dataset.txt +++ b/dataset.txt @@ -1 +1,24 @@ -[SYS]ты полезный робот помощник[USER]привет[AI]привет как дела? \ No newline at end of file +[SYS]ты полезный робот помощник[USER]привет[AI]привет как дела? +[SYS]ты полезный робот помощник[USER]помоги составить меню на ужин из курицы и грибов[AI]Конечно! Можно приготовить классическое фрикасе в сливочном соусе или запечь куриное филе с грибами под сырной шапкой. Что звучит аппетитнее? +[SYS]ты полезный робот помощник[USER]как в Python быстро объединить два списка без дубликатов?[AI]Используй преобразование в множество: list(set(list1) | set(list2)). Это самый быстрый и лаконичный способ. +[SYS]ты полезный робот помощник[USER]мне нужно написать короткое поздравление для коллеги с днем рождения[AI]Держи вариант: «С днем рождения! Желаю крутых проектов, неиссякаемого вдохновения и чтобы работа всегда была в радость. Ура!» +[SYS]ты полезный робот помощник[USER]почему небо синее?[AI]Это происходит из-за релеевского рассеяния: солнечный свет взаимодействует с атмосферой, и короткие волны синего цвета рассеиваются сильнее остальных. +[SYS]ты полезный робот помощник[USER]придумай три идеи для стартапа в 2024 году[AI]1. Платформа для аренды домашних инструментов через ИИ-подбор. 2. Сервис автоматизации «цифрового детокса». 3. Агрегатор экологичных локальных фермерских продуктов. +[SYS]ты полезный робот помощник[USER]что делать, если не выспался, а впереди важный день?[AI]Пей больше воды, прими контрастный душ и старайся делать самые сложные задачи в первой половине дня, пока держится остаток концентрации. +[SYS]ты полезный робот помощник[USER]напиши завязку для детективного романа[AI]«Утром на столе известного антиквара лежал предмет, который он сам лично уничтожил двадцать лет назад. Дверь была заперта изнутри, а камеры не зафиксировали ни одного движения». +[SYS]ты полезный робот помощник[USER]как правильно составить договор аренды квартиры?[AI]Обязательно укажи паспортные данные сторон, опиши состояние имущества, зафиксируй сумму залога и условия его возврата, а также приложи опись техники и мебели. +[SYS]ты полезный робот помощник[USER]составь план тренировки на 15 минут дома[AI]Начни с разминки (2 мин), затем сделай 3 круга: приседания (15 раз), отжимания (10 раз) и планка (45 сек). В конце — легкая растяжка. +[SYS]ты полезный робот помощник[USER]найди ошибку в предложении: «Он одел пальто и вышел»[AI]Ошибка в употреблении глагола. Правильно говорить «надел пальто». Запомни: одевают кого-то, а надевают на себя. +[SYS]ты полезный робот помощник[USER]в чем смысл цитаты «Я знаю, что ничего не знаю»?[AI]Это парадокс Сократа. Он означает, что чем больше человек познает мир, тем яснее он осознает масштаб того, что ему еще неизвестно. +[SYS]ты полезный робот помощник[USER]порекомендуй книгу по саморазвитию[AI]Попробуй «Атомные привычки» Джеймса Клира. Она дает конкретные инструменты, как внедрять полезные изменения в жизнь маленькими шагами. +[SYS]ты полезный робот помощник[USER]как перевести «I'm looking forward to it» на русский?[AI]Самый точный вариант: «Я с нетерпением этого жду» или «Я очень жду этого». +[SYS]ты полезный робот помощник[USER]что приготовить на завтрак за 5 минут?[AI]Овсянка в микроволновке с бананом или тост с авокадо и яйцом-пашот. Быстро, полезно и сытно! +[SYS]ты полезный робот помощник[USER]как работает блокчейн простыми словами?[AI]Это как цифровая тетрадь, записи в которой нельзя стереть или изменить. Копия этой тетради есть у каждого участника, поэтому обмануть систему невозможно. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]как сбросить кэш DNS в Windows?[AI]Запусти командную строку от имени администратора и введи: ipconfig /flushdns. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]в чем разница между TCP и UDP?[AI]TCP гарантирует доставку данных и порядок пакетов; UDP работает быстрее, но не проверяет доставку. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]почему ноутбук сильно шумит?[AI]Основные причины: запыление системы охлаждения, высыхание термопасты или высокая фоновая нагрузка на процессор. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]как проверить статус порта 8080 на Linux?[AI]Используй команду: sudo lsof -i :8080 или netstat -tuln | grep 8080. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]что такое рекурсия в программировании?[AI]Это процесс, при котором функция вызывает саму себя в своем теле до достижения базового условия. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]какой SQL-запрос удаляет таблицу?[AI]Команда: DROP TABLE название_таблицы;. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]зачем нужен Docker?[AI]Для контейнеризации приложений, обеспечивающей идентичную работу программы на любой ОС. +[SYS]ты технический эксперт, отвечай кратко и по делу[USER]как быстро найти процесс по имени и убить его в Linux?[AI]Используй: pkill имя_процесса. \ No newline at end of file diff --git a/main b/main new file mode 100755 index 0000000..7e88108 Binary files /dev/null and b/main differ diff --git a/main.cpp b/main.cpp index d6bf2c5..a7eef13 100644 --- a/main.cpp +++ b/main.cpp @@ -6,16 +6,15 @@ #include #include #include -#include "Xenith/core.h" -#include "Xenith/token/token.h" -#include +#include "Xenith/core.hpp" +#include "Xenith/token/token.hpp" #include std::string currentSystemPrompt = ""; LayerStructure_t layers[] = { {MAX_CONTEXT * EMBED_DIM, SIGMOID}, - {16, SIGMOID}, + {256, SIGMOID}, {MAX_VOCAB, SIGMOID} }; @@ -71,8 +70,7 @@ void trainOnSequence(NeuralNetwork& nn, Tokenizer& tok, Embedder& emb, const std std::cout << "Training logic: Next Token Prediction..." << std::endl; - std::cout << "\033[s\033[999;1H" << "\033[2K" << "\033[1;30m" << "\033[F" << "\r" - << "DATA: " << (sequenceStr.length() > 100 ? sequenceStr.substr(0, 200) : sequenceStr) << "\033[0m\033[u"; + std::cout << "\033[s\n\n"; for (int e = 1; e <= epochs; e++) { double totalLoss = 0; @@ -84,26 +82,22 @@ void trainOnSequence(NeuralNetwork& nn, Tokenizer& tok, Embedder& emb, const std trainSteps++; auto currentTime = std::chrono::high_resolution_clock::now(); - if (std::chrono::duration(currentTime - startTime).count() >= 1.0) { + if (std::chrono::duration(currentTime - startTime).count() >= 0.1) { stepsPerSec = trainSteps / std::chrono::duration(currentTime - startTime).count(); trainSteps = 0; startTime = currentTime; } - std::cout << "\rEpoch " << std::setw(4) << e << "/" << epochs - << " | Token: " << std::setw(3) << i << "/" << allTokens.size() - << " | Loss: " << std::fixed << std::setprecision(6) << totalLoss - << " | Max Loss: " << std::fixed << std::setprecision(6) << maxLoss << " \033[s"; + std::cout << "\033[u"; - std::cout << "\033[999;1H" << "\r"; + std::cout << "Epoch " << std::setw(4) << e << "/" << epochs + << " | Token: " << std::setw(4) << i << "/" << allTokens.size() + << " | Loss: " << std::fixed << std::setprecision(6) << totalLoss + << " | Max Loss: " << maxLoss << "\033[K\n"; - std::cout << "SPEED: " << std::setw(6) << std::fixed << std::setprecision(1) << stepsPerSec << " st/s" - << " | MODEL: " << std::setw(7) << modelSizeStr - << " | CURRENT: [" << std::left << std::setw(15) << tok.getWord(allTokens[i]) << "] (" - << std::right << std::setw(4) << allTokens[i] << ") "; - - std::cout << "\033[K" << "\033[0m"; - - std::cout << "\033[997;1H" << "\r" << std::flush << "\033[u"; + std::cout << "SPEED: " << std::setw(6) << std::fixed << std::setprecision(1) << stepsPerSec + << " st/s | MODEL: " << std::setw(7) << modelSizeStr + << " | CURRENT: [" << std::left << std::setw(15) << tok.getWord(allTokens[i]) << "]" + << "\033[K" << std::flush; } maxLoss = totalLoss; @@ -114,9 +108,6 @@ void trainOnSequence(NeuralNetwork& nn, Tokenizer& tok, Embedder& emb, const std int main() { - SetConsoleOutputCP(CP_UTF8); - SetConsoleCP(CP_UTF8); - Tokenizer tok; Embedder emb(MAX_VOCAB, EMBED_DIM);