我微调了自己的”第二大脑“

多年来,我的笔记只是些毫无生气的文本文件,直到我用它们微调了一个1B参数的语言模型。

我微调了自己的”第二大脑“

我遗忘的项目想法。我从未重复利用的研究见解。埋藏在文件夹里的来之不易的经验教训。

上周,我做了一件非常规的事情。

我用自己的“脑力转储”微调了一个 10 亿参数的语言模型——现在它能像我的第二个大脑一样回答问题。

说实话?这比我想象的要让我感到恐惧得多。

1、我的“第二大脑”其实是个信息坟场

和大多数科技从业者一样,我囤积了大量信息:

  • Markdown 文件
  • Notion 页面
  • 研究 PDF
  • 未完成的项目文档
  • 凌晨两点的奇思妙想

纸面上,我拥有一个“知识系统”。

但实际上:

  • 我无法有效地搜索它。
  • 我无法将各种想法联系起来。
  • 我更无法用它进行思考。

每次需要什么东西时,我都会回到 Google、ChatGPT 或 Stack Overflow——即使答案早已存在于我的笔记中。

这种矛盾最终让我崩溃。

2、我为什么不使用 RAG(争议部分)

没错,我本可以构建一个标准的 RAG(检索增强生成)流程:

  • 嵌入笔记
  • 存储向量
  • 检索信息块
  • 将它们传递给 GPT-4

我做过很多次了。

但我被四个大问题困扰:

  • 它听起来不像我。它的回答像个助手,而不是我自己的思考。
  • 上下文总是泄露。除非我把长期假设硬塞进每个提示里,否则它会忘记。
  • 隐私感觉很虚假。我的研究和私人想法不断地从我的电脑里流出。
  • 它搜索而不是记忆。我想要的不是检索,而是内化的知识。

然后我突然想到:

如果我的笔记不被搜索呢……如果它们被学习呢?

RAG让我能够获取信息。微调让我能够理解我的推理过程。

一个负责搜索,另一个负责记忆。

我想要的不是一个搜索我过去的搜索引擎。

我想要的是一个浓缩版的我的思维。

3、疯狂的实验:训练我自己的“个人学习逻辑模型”

于是,我停止了检索我的知识……

……并决定训练一个模型来理解我的思维模式。

我没有使用 700 亿参数的巨型模型,而是使用了一个 10 亿参数的模型。

它既小到可以在本地运行,又大到足以进行泛化。

目标很简单:

如果我问一个我以前写过的问题,它应该给出和我六个月前一样的答案。

如果失败了,我最多也就浪费几个小时。如果成功了,我就能和自己的想法对话了。

3、第一次真正的测试(事情从这里开始变得奇怪)

训练完成后,我问了它一个我从未明确写成问答题的问题:

“我的 AI 项目中总是出现什么错误?”

ChatGPT 通常会给出一些通用建议:

“您可能低估了数据质量或架构过于复杂……”

而我微调后的模型则回答道:

“您总是先优化模型,然后再验证问题是否值得解决。您在 GPS 追踪项目、阿萨姆语 NLP 分类器和 SQL 自动化工具中都犯了同样的错误。在这三个案例中,您后来都简化了流程。”

这真让人难受。

因为它完全正确——而且具体得令人痛苦。

它不仅仅是发现了事实。它已经学会了我失败的模式。

就在那一刻,这个实验不再像是一个演示,而更像是一面镜子。

4、代码附录:我是如何进行微调的

这就是我使用的完整技术栈。它完全免费(如果您已经拥有 GPU),并且能够 100% 保护您的数据隐私。

硬件配置

  • GPU:NVIDIA RTX 3060(12 GB 显存)
  • 内存:16 GB 系统内存
  • 操作系统:Ubuntu 22.04(WSL2 也适用)
  • 训练时间:约 2.5 小时

4.1 环境与模型选择

我使用了:

  • Llama-3.2–1B-Instruct → 最适合写作和推理
  • 备选方案:Qwen-2.5–1.5B-Instruct → 更适合逻辑/编码

复制以下命令:

pip install "transformers>=4.45.0" "datasets" "accelerate" "peft" "bitsandbytes" "sentencepiece"

4.2 将笔记转换为数据集

我将杂乱的 Markdown 笔记转换为(指令,回复)对。

import json
from pathlib import Path

DATA_DIR = Path("./my_notes")
OUTPUT_FILE = Path("train.jsonl")

def build_dataset():
    data = []
    for path in DATA_DIR.rglob("*.md"):
        content = path.read_text(encoding="utf-8", errors="ignore").strip()
        if len(content) < 100:
            continue
        
        topic = path.stem.replace("-", " ").title()
        entry = {
            "instruction": f"Explain my thoughts on {topic}.",
            "response": content
        }
        data.append(entry)

    with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
        for entry in data:
            f.write(json.dumps(entry) + "\n")

    print(f"Converted {len(data)} notes.")

build_dataset()

4.3 关键的分词步骤

⚠️ 大多数教程都会在这里出错。如果您使用 padding="max_length" 而不将填充标记掩码设置为 -100,模型将学习如何预测沉默。

from transformers import AutoTokenizer
from datasets import load_dataset

MODEL_ID = "meta-llama/Llama-3.2-1B-Instruct"

tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
tokenizer.pad_token = tokenizer.eos_token

dataset = load_dataset("json", data_files="train.jsonl", split="train")

PROMPT_TEMPLATE = """You are a specific version of Manash's brain.

### Instruction:
{instruction}

### Response:
{response}
"""

def format_and_tokenize(example):
    text = PROMPT_TEMPLATE.format(
        instruction=example["instruction"],
        response=example["response"]
    )

    tokens = tokenizer(
        text,
        truncation=True,
        max_length=1024,
        padding="max_length"
    )

    tokens["labels"] = [
        -100 if t == tokenizer.pad_token_id else t
        for t in tokens["input_ids"]
    ]

    return tokens

tokenized_dataset = dataset.map(format_and_tokenize)

4.4 QLoRA 微调(训练)

这才是真正考验脑力的地方。

import torch
from transformers import AutoModelForCausalLM, TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model
from transformers import BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16
)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_ID,
    quantization_config=bnb_config,
    device_map="auto"
)

peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=["q_proj", "v_proj"]
)

model = get_peft_model(model, peft_config)

args = TrainingArguments(
    output_dir="llama-personal-brain",
    per_device_train_batch_size=1,
    gradient_accumulation_steps=8,
    num_train_epochs=3,
    learning_rate=2e-4,
    fp16=True,
    logging_steps=10,
    save_strategy="epoch"
)

trainer = Trainer(
    model=model,
    args=args,
    train_dataset=tokenized_dataset,
)

trainer.train()
model.save_pretrained("final_adapter")

4.5 使用你的新大脑

from transformers import pipeline

pipe = pipeline(
    "text-generation",
    model=MODEL_ID,
    device_map="auto"
)

pipe.model.load_adapter("final_adapter")

def ask_brain(question):
    prompt = f"""You are a specific version of Manash's brain.

### Instruction:
{question}

### Response:
"""
    out = pipe(prompt, max_new_tokens=200, temperature=0.7)
    return out[0]["generated_text"]

print(ask_brain("Why did my first RAG pipeline fail?"))

5、值得吗?

优点:

  • 隐私:100% 离线运行
  • 速度:消费级 GPU 可瞬间处理 10 亿参数的模型
  • 一致性:像你一样思考,而非像通用助手

缺点:

  • 幻觉:它可能会凭空捏造信息,超出你的笔记范围
  • 时间冻结:它只知道你在训练时掌握的知识

6、奇怪的心理副作用

在它开始运行良好几天后,意想不到的事情发生了。

我不再问它技术问题。我开始问它,为什么我几年前会做出某些决定。

为什么我放弃了某些项目。为什么我总是重复同样的架构错误。为什么我总是先优化后验证。

有时它会为我辩护。有时它会揭露我的错误。

它不再像一个聊天机器人。

它感觉像是一个压缩版的、带有强烈个人观点的过去的自己。

而这……让我感到非常不舒服。

7、最终思考

每个人都在竞相打造超级智能。

一个能够同时了解:一切,所有地方,所有事物的东西。

我无意间构建了一种特定智能。

它能记住:

  • 我的推理方式,
  • 我的失败经历,
  • 以及我不断重复的模式。

它不会取代我的思维。

它会直面我的思维。

说实话?

这比我能想象到的任何超级智能都更令人不安。


原文链接:I Fine-Tuned a 1B Model on My Personal Notes — It Now Thinks Like My Second Brain

汇智网翻译整理,转载请标明出处