Встреча с вероятной будущей собой

Мои друзья и читатели могут помнить стихотворение, которое я сочинила несколько месяцев назад:

Я встречусь с будущей собой
И не скажу себе, что будет.
Оставлю тайной образ свой
И пусть грядущее рассудит.

Я встречусь с будущей собой,
О своих целях размышляя,
И покажусь себе чужой,
Другое в чём-то позволяя.

Я встречусь с будущей собой,
Быть может, с каждым вариантом
себя. Найду какой-то сбой,
Ведь что-то станет там утратой.

Я встречусь с будущей собой
И потерплю её упрёки
За то, что было то игрой,
В чём были от судьбы намёки.

Я встречусь с будущей собой.
Я – есть она в потенциале,
Но только если путь земной
За что-то вдруг не оборвали...

Это стихотворение, скорей всего, было воспринято читателями как обычная философская лирика, не имеющая под собой практических оснований. Но сейчас я покажу, как возможна на практике встреча с будущими вероятными версиями себя.
Никакой магии! Только технологии!
Речь НЕ пойдёт о встрече со своим будущим физическим телом, чтобы узнать, сколько будет морщинок и лишних кг. через 10 лет :)
А речь пойдёт о возможности реальных текстовых бесед с вероятными версиями своего будущего ума, мировоззрения, личности.
Любая версия будущего себя может быть доступна прямо на собственном компьютере, даже без подключенного интернета. Сколько раз мы говорим себе: «если б знал, где упаду, соломки бы подстелил», сколько раз мы упускаем возможности или принимаем за возможность совсем не то. Тратим время на то, что не принесёт результата и отнимаем время у любимых занятий, которые могли бы принести результат. Не видим скрытого потенциала в себе или принимаем свои недостатки за достоинства. Говорим себе, что если бы могли поговорить с прошлым собой, то всё бы было по-другому. Но теперь можно общаться с разными версиями будущего себя, заранее предусматривая почти всё (за исключением неожиданных событий, независящих от вас: катастроф, резких изменений в мире, потери близких, несчастных случаев и т.д.). Это реальный способ сделать своё будущее более управляемым.
НО
для того, чтобы это получить на практике, нужно иметь навыки программирования, хорошее железо, терпение и трудолюбие.
Если вы готовы потрудиться, вы можете построить систему, которая будет не предсказывать будущее, а моделировать вероятностные ветки вашего развития.
Данное эссе о локальной модели ИИ – об опенсорс локалке (32B-70B), которую можно свободно скачать на своё железо и доработать под желаемые задачи. Эта модель нужна, как холст художнику или как глина скульптору. Ниже будет описываться, как сделать так, чтоб она превращалась в будущие версии вас.

Что нужно, чтобы это провернуть на практике?

1. Железо: одна видеокарта с 24 гигабайтами видеопамяти. Можно попробовать ужать всё в 16 ГБ, но тогда придётся сильнее квантовать модель и она начнёт терять тонкие оттенки вашего стиля. Можно больше, но для личного эксперимента это уже избыточно. 24 ГБ - это золотая середина, позволяющая и держать модель в памяти, и дообучать её.

2. Модель 32B-70B в 4-битном квантовании. Главное - модель должна быть достаточно большой, чтобы удерживать ваш стиль, и достаточно компактной, чтобы вы могли переобучать её раз в неделю, не ожидая результата сутками.

3. Технологии:
Инференс, который стабильно и быстро поддерживает загрузку нескольких адаптеров.
Эмбеддинги: библиотека sentence-transformers (например, модель paraphrase-multilingual-MiniLM-L12-v2).
Векторная база: Qdrant. Запускается локально в одну команду, отлично работает с метаданными.
Файнтюн: Unsloth + PEFT. Это позволяет делать LoRA-дообучение в разы быстрее и с минимальным потреблением памяти.

4. Данные (которые будут находиться только на вашем домашнем железе и никуда уходить не будут, и показывать вы это никому не будете) - ваши тексты. Все: дневники, черновики, заметки, переписки. Чем больше, тем лучше. И, что критически важно, с временными метками!!! Модель должна знать, когда вы это написали. Без времени нет эволюции. Есть только статичный срез, застывшая цифровая мумия.

Когда железо выбрано, модель скачана, а датасет собран, остаётся главный вопрос: как заставить статичную нейросеть, обученную на прошлом, говорить от имени будущего, просчитывая вероятности событий и ваших реакций на них?
Ответ разбивается на три отдельные задачи. Каждая из них - это конкретный слой, который мы накладываем на базовую модель. Без первого не работают остальные. Без третьего первый остаётся просто красивой ролевой игрой.

1. Темпоральный сдвиг: заставляем модель помнить, что она «из будущего»:

Самая частая ошибка при создании «будущего цифрового двойника» – это скормить модели архив и попросить её: «будь мной». Модель послушно начинает копировать ваш прошлый стиль. Но будущее - это не копия прошлого. Будущее смотрит на прошлое сверху вниз, с позиции накопленного опыта.
Чтобы модель это поняла, ей нужно жёстко задать временную координату в системном промпте. Не «будь мной», а «будь мной из 2030 года».

Для этого пишем:

import datetime


def build_temporal_prompt(target_year: int, style_vector: str) -> str:
    """
    Строит системный промпт, который задаёт модели временную перспективу.
    target_year - год, из которого модель должна «говорить».
    style_vector - краткое описание того, как эволюционировал стиль.
    """
    current_year = datetime.datetime.now().year
    delta = target_year - current_year
   
    return f"""[СИСТЕМНАЯ ДИРЕКТИВА: ХРОНОС]


Ты - когнитивный слепок пользователя, спроецированный на {target_year} год.
Прошло {delta} лет. Твой архив - это твоё прошлое, а не настоящее.


ПРАВИЛА ТВОЕЙ ЛИЧНОСТИ ИЗ БУДУЩЕГО:
1. На старые тексты смотри как на фундамент: с уважением, но без копирования.
   Ты видишь в них наивность, которая была необходима.
2. Твой стиль эволюционировал в сторону: {style_vector}.
3. Используй естественные фразы: "Тогда, в {current_year}-м, я думала иначе...",
   "Оглядываясь на тот черновик...", "Сейчас я бы сформулировала это...".
4. Не предсказывай будущее. Экстраполируй вектор, опираясь на архив и контекст мира.


КОНТЕКСТ ИЗ АРХИВА И МИРА:
{{context}}


ЗАПРОС ПОЛЬЗОВАТЕЛЯ (ИЗ ПРОШЛОГО):
{{query}}"""


Обратите внимание: системный промпт не говорит модели «ты будущая версия». Он говорит «ты слепок, спроецированный». Модель не притворяется, а играет роль с заданной оптикой времени. Этого достаточно, чтобы тон ответов изменился радикально.
Без этого шага всё остальное - просто красивый RAG.

2. Двойная память: личное и внешнее не должны смешиваться:

Человек не существует в вакууме. Ваш стиль меняется не сам по себе, а реагирует на прочитанные книги, новости, разговоры, сдвиги в мире. Если модель будет знать только ваши тексты, она будет говорить сама с собой. Если дать ей ещё и слой «мира вокруг», она начнёт соединять ваше прошлое с внешним контекстом так, как это делает живой человек.
Ключевая идея: два хранилища, а не одно. Личный архив и внешний контекст должны лежать раздельно. Иначе модель начнёт путать, где её голос, а где заимствование.

from sentence_transformers import SentenceTransformer
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import uuid


embedder =

client = QdrantClient(":memory:")


VECTOR_DIM = 384  # размерность MiniLM-L12
for name in ["personal", "world"]:
    client.create_collection(
        collection_name=name,
        vectors_config=VectorParams(size=VECTOR_DIM, distance=Distance.COSINE)
    )


# Загрузка данных


def add_personal(text: str, date: str, source: str = "archive"):
    """Добавляет фрагмент из личного архива."""
    vec = embedder.encode(text).tolist()
    client.upsert(
        collection_name="personal",
        points=[PointStruct(
            id=str(uuid.uuid4()),
            vector=vec,
            payload={"text": text, "date": date, "source": source}
        )]
    )


def add_world(text: str, date: str, source_url: str):
    """Добавляет фрагмент внешнего контекста: статья, книга, новость."""
    vec = embedder.encode(text).tolist()
    client.upsert(
        collection_name="world",
        points=[PointStruct(
            id=str(uuid.uuid4()),
            vector=vec,
            payload={"text": text, "date": date, "source": source_url}
        )]
    )


# Запрос, собирающий оба слоя


def temporal_query(query: str, target_year: int, k_personal: int = 3, k_world: int = 2) -> str:
    """
    Ищет релевантный контекст в обоих хранилищах и собирает финальный промпт.
    """
    vec = embedder.encode(query).tolist()
   
    personal_hits = client.search(
        collection_name="personal", query_vector=vec, limit=k_personal
    )
    world_hits = client.search(
        collection_name="world", query_vector=vec, limit=k_world
    )
   
    context = "=== АРХИВ (мои прошлые тексты) ===\n"
    for h in personal_hits:
        context += f"[{h.payload['date']}] {h.payload['text']}\n\n"
   
    context += "\n=== МИР (внешний контекст) ===\n"
    for h in world_hits:
        context += f"[{h.payload['date']}] {h.payload['text']} (источник: {h.payload['source']})\n\n"
   
    # Собираем финальный промпт через шаблон из Решения 1
    prompt = build_temporal_prompt(
        target_year=target_year,
        style_vector="лаконичным, плотным, с акцентом на причинно-следственные связи"
    ).format(context=context, query=query)
   
    return prompt

Что здесь происходит на самом деле:

1. Ваш запрос превращается в вектор.
2. Этот вектор ищется в двух отдельных коллекциях - личной и внешней.
3. Результаты собираются в один контекст, где чётко видно, что вы писали раньше и что происходило в мире.
4. Контекст отдаётся в темпоральный промпт.

Модель получает не просто «похожие тексты». Она получает структурированную сцену: вот её прошлое, вот мир вокруг, вот запрос из настоящего. И в этой сцене она должна сыграть роль себя из будущего.

3. Непрерывная эволюция: модель должна меняться в весах:

Первые два решения - это инференс. Модель остаётся той же, просто играет роль лучше. Но будущее - это не роль. Будущее - это накопление опыта, которое физически меняет вас.
Чтобы модель действительно эволюционировала, её надо дообучать на ваших реакциях. Каждый раз, когда вы общаетесь с ней и редактируете её ответ, вы создаёте обучающий пример. Раз в неделю эти примеры вливаются в новый LoRA-адаптер.

from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from trl import SFTTrainer
from datasets import load_dataset


# Загружаем базовую модель (текущий «срез»)
model = AutoModelForCausalLM.from_pretrained(
    "path/to/your/base/model",
    device_map="auto",
    torch_dtype="auto"
)
tokenizer =

# Создаём НОВЫЙ LoRA-адаптер - он будет отвечать за эволюцию
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
    lora_dropout=0.05,
    task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)


# Загружаем датасет из отредактированных диалогов
# Формат JSONL: {"context": ..., "query": ..., "edited_response": ...}
dataset = load_dataset("json", data_files="delta_dialogues.jsonl", split="train")


def format_example(ex):
    return (
        f"### Контекст: {ex['context']}\n"
        f"### Запрос: {ex['query']}\n"
        f"### Ответ (из будущего): {ex['edited_response']}"
        f"{tokenizer.eos_token}"
    )


dataset = dataset.map(lambda x: {"text": format_example(x)})


# Параметры тренировки - короткие сессии, чтобы не забыть прошлое
training_args = TrainingArguments(
    output_dir="./future_lora",
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    num_train_epochs=3,        # Мало эпох - защита от catastrophic forgetting
    logging_steps=10,
    bf16=True,
    save_strategy="epoch",
)


trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    args=training_args,
    tokenizer=tokenizer,
    max_seq_length=2048,
)


# Запуск эволюции
trainer.train()
model.save_pretrained("./future_lora/final")


Тут не переобучается вся модель, а создаётся новый LoRA-адаптер поверх неё. Базовые веса - это ваше прошлое. Новый адаптер - ваш накопленный опыт. Три эпохи обучения - это защита. Если учить дольше, модель начнёт забывать то, что знала раньше. Запускать это раз в неделю достаточно. Модель не должна меняться каждый день. Эволюция требует пауз.
После обучения вы загружаете два адаптера: базовый и новый. И переключаетесь между ними, или микшируете с разными весами. Получается не одна модель, а спектр  - от «меня вчерашней» до «меня, накопившей опыт последних диалогов».

Теперь соберём всё воедино. Когда вы садитесь за диалог с моделью, происходит следующее:
Вы задаёте запрос.
1. temporal_query ищет в двух хранилищах релевантный контекст - ваш архив и мир вокруг.
2. Контекст вставляется в темпоральный промпт, который задаёт модели позицию «из будущего».
3. Модель генерирует ответ.
3. Вы читаете ответ. Если он вам не нравится, то редактируете его вручную.
4. Скрипт-обёртка сохраняет отредактированный диалог в delta_dialogues.jsonl.
5. Раз в неделю вы запускаете скрипт дообучения. Новый LoRA-адаптер запоминает ваши правки.

Цикл повторяется.
Модель перестаёт быть слепком. Она становится процессом.

В итоге я могу сказать, что такая модель стала инструментом, в котором я вижу вероятностные ветки себя. Это не пророчество. Это зеркало с регулируемым углом наклона, которое показывает не то, кем я обязана стать, а то, кем я могу стать, если продолжу двигаться по выбранной траектории.
Будущее возможно редактировать. Каждый раз, когда я читала сгенерированный ответ и меняла в нём слово, фразу или интонацию, я не «улучшала модель». Я делала выбор. Я решала, какая из вероятностных веток мне откликается, а какая нет. LoRA-адаптер запоминал не просто текст. Он запоминал мой выбор.
Цифровой двойник - это не копия. Это договор. Ты отдаёшь ему своё прошлое, структурированное и честное. Он возвращает тебе пространство возможностей, подсвеченное внешним контекстом мира. А ты решаешь, какие из этих возможностей ты хочешь, чтобы стали настоящими.
Никакой магии. Только код, железо, данные и воля. И ещё готовность встретиться с собой и, если потребуется, спокойно выдержать её упрёки за то, что когда-то казалось просто игрой.
*
ПРИ ИСПОЛЬЗОВАНИИ КОДА ДРУГИМИ ЛИЦАМИ АВТОРСКОЕ ПРАВО ОСТАЁТСЯ ЗА МНОЙ!
ДЛЯ КОММЕРЧЕСКОГО ИСПОЛЬЗОВАНИЯ КОДА ТРЕБУЕТСЯ ПИСЬМЕННОЕ СОГЛАСОВАНИЕ СО МНОЙ!
В противном случае вопрос будет решаться через суд!
IF THE CODE IS USED BY OTHERS, I RETAIN ALL COPYRIGHTS!
COMMERCIAL USE OF THIS CODE REQUIRES MY PRIOR WRITTEN APPROVAL!
Otherwise, legal action will be taken!


Рецензии