This commit is contained in:
KoDer 2026-09-29 20:21:46 +07:00
parent 5a072d314d
commit 41aa593019
4 changed files with 67 additions and 23 deletions

View File

@ -1,22 +1,18 @@
cmake_minimum_required(VERSION 3.20)
project(Xenith)
set(CMAKE_CXX_STANDARD 17) # В Makefile указан c++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Опции компиляции из твоего Makefile
# Для Debug сборки CLion обычно сам добавляет -O0 -g, но можно форсировать
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "-O1 -g -fsanitize=address,undefined")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-fsanitize=address,undefined")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -ffast-math -funroll-loops")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -funroll-loops")
endif()
# Добавляем предупреждения
add_compile_options(-Wall -Wextra -Wno-unused-parameter)
# Список исходных файлов из твоего Makefile
set(SOURCES
main.cpp
xenith/core/model.cpp

View File

@ -3,11 +3,6 @@
Трансформер на чистом C++: обучение и генерация текста на CPU, без внешних
зависимостей. Всё в одном бинарнике.
```
make # собрать -> bin/xenith
./bin/xenith --help
```
## Что внутри
Архитектура — как у LLaMA: pre-norm, RMSNorm, RoPE, SwiGLU, связанные
@ -28,15 +23,15 @@ make # собрать -> bin/xenith
```bash
# 1) собрать модель из своего текста
./bin/xenith new models/my.xnh --corpus data.txt \
./bin/Xenith new models/my.xnh --corpus data.txt \
--vocab 512 --embd 128 --layers 6 --heads 8 --ctx 256
# 2) обучить
./bin/xenith train models/my.xnh --corpus data.txt \
./bin/Xenith train models/my.xnh --corpus data.txt \
--out models/my_trained.xnh --steps 5000 --batch 16 --lr 3e-4
# 3) сгенерировать
./bin/xenith gen models/my_trained.xnh --prompt "Привет" --n 200 --temp 0.8
./bin/Xenith gen models/my_trained.xnh --prompt "Привет" --n 200 --temp 0.8
```
## Команды
@ -105,9 +100,9 @@ make # собрать -> bin/xenith
### info / gradcheck / bench
```bash
./bin/xenith info models/my.xnh # конфигурация и словарь
./bin/xenith gradcheck # градиенты против численных
./bin/xenith bench models/my.xnh # скорость
./bin/Xenith info models/my.xnh # конфигурация и словарь
./bin/Xenith gradcheck # градиенты против численных
./bin/Xenith bench models/my.xnh # скорость
```
`gradcheck` стоит запускать после любой правки в `model.cpp` / `backward.cpp` —

View File

@ -77,12 +77,13 @@ static void usage() {
xenith <команда> [опции]
КОМАНДЫ
new создать новую модель из корпуса
train обучить существующую модель
gen сгенерировать текст
info показать конфигурацию модели
gradcheck проверить градиенты численно
bench замерить скорость форварда и шага обучения
new создать новую модель из корпуса
train обучить существующую модель
gen сгенерировать текст
info показать конфигурацию модели
gradcheck проверить градиенты численно
bench замерить скорость форварда и шага обучения
ollama запустьтить сервер с api ollama
ПРИМЕРЫ
xenith new model.xnh --corpus data.txt --vocab 512 --embd 64 --layers 4 --heads 4
@ -131,6 +132,10 @@ static void usage() {
--no-stream не печатать в процессе
--batch "a;b;c" несколько промптов через ;
--show-tokens показать id токенов
ОПЦИИ ollama
--port PORT порт на котором будет открыт сервер
--conf NAME.conf
)");
}
@ -297,6 +302,53 @@ static int cmd_bench(const Args& a) {
return run_bench(ck, a.geti("iters", 20), a.geti("block", 64));
}
static int cmd_ollama(const Args& a) {
if (a.pos.empty()) { fprintf(stderr, "gen: укажите файл модели\n"); return 1; }
Checkpoint ck;
std::string err;
if (!load_checkpoint(a.pos[0], ck, err)) { fprintf(stderr, "gen: %s\n", err.c_str()); return 1; }
GenConfig gc;
gc.max_new_tokens = a.geti("n", 200);
gc.temperature = a.getf("temp", 0.8f);
gc.top_k = a.geti("top-k", 40);
gc.top_p = a.getf("top-p", 0.95f);
gc.seed = a.geti("seed", -1);
gc.stream = !a.has("no-stream");
if (a.has("batch")) {
std::vector<std::string> prompts;
std::string s = a.get("batch");
size_t start = 0;
while (start <= s.size()) {
size_t p = s.find(';', start);
if (p == std::string::npos) { prompts.push_back(s.substr(start)); break; }
prompts.push_back(s.substr(start, p - start));
start = p + 1;
}
gc.stream = false;
std::vector<std::string> outs = generate_batch(ck.params, ck.tok, prompts, gc);
for (size_t i = 0; i < outs.size(); ++i) {
printf("=== промпт %zu: %s\n%s\n\n", i + 1, prompts[i].c_str(), outs[i].c_str());
}
return 0;
}
std::string prompt = a.get("prompt", "");
if (a.pos.size() > 1) prompt = a.pos[1];
std::vector<int> ids;
std::string text = generate(ck.params, ck.tok, prompt, gc, &ids);
if (a.has("show-tokens")) {
printf("\n--- токены (%zu) ---\n", ids.size());
for (size_t i = 0; i < ids.size(); ++i)
printf("%d ", ids[i]);
printf("\n");
}
return 0;
}
int main(int argc, char** argv) {
if (argc < 2) { usage(); return 1; }
const std::string cmd = argv[1];
@ -309,6 +361,7 @@ int main(int argc, char** argv) {
if (cmd == "info") return cmd_info(a);
if (cmd == "gradcheck") return cmd_gradcheck(a);
if (cmd == "bench") return cmd_bench(a);
if (cmd == "ollama") return cmd_bench(a);
fprintf(stderr, "неизвестная команда: %s\n\n", cmd.c_str());
usage();

BIN
models/my.xnh Normal file

Binary file not shown.