-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add CAFUNE-mini experiment foundation #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # CAFUNE — guia de colaboração | ||
|
|
||
| ## Fluxo Git e releases | ||
|
|
||
| - `main` é a linha estável: mantenha-a verde no CI e não faça commits diretos. | ||
| - Todo trabalho começa em uma branch publicada e integrada por pull request. | ||
| - Use `feature/<hipotese>` para capacidades ou experimentos, por exemplo | ||
| `feature/cafune-mini`, `feature/mha-baseline` e `feature/tokenizer-ablation`. | ||
| - Use `fix/<problema>` para correções. Para uma correção urgente de uma release | ||
| publicada, use `hotfix/<problema>`. | ||
| - Releases são tags semânticas (`v0.1.0`, `v0.1.1`). Crie `release/vX.Y` apenas | ||
| quando for necessário manter correções nessa linha sem incluir trabalho novo. | ||
| - Não misture hipóteses experimentais diferentes na mesma branch ou PR. | ||
|
|
||
| ## Contratos técnicos | ||
|
|
||
| - A implementação canônica é `julia/src/`; não reviva `julia/train_unified.jl` | ||
| nem lançadores legados como uma segunda fonte do modelo. | ||
| - `config/research.toml` define a configuração de pesquisa canônica. | ||
| - `config/experiments/cafune-mini.toml` é a configuração de ~7,07M parâmetros | ||
| para ablações. Preserve tokenizer, dados e splits ao comparar mini vs baseline. | ||
| - `python/dataset_splits.json` é o contrato de splits determinísticos. Se o | ||
| dataset tokenizado mudar, regenere os splits antes de treinar ou avaliar. | ||
| - O melhor checkpoint é escolhido por `aggregate.loss_mean` da avaliação de | ||
| validação; nunca por loss de treino. | ||
| - Antes de iniciar um treino comparável, registre hipótese e controles em | ||
| `docs/EXPERIMENTS.md`. Só registre conclusões após existir avaliação | ||
| reproduzível. | ||
| - Checkpoints, avaliações geradas, logs, caches e mmap são artefatos de runtime, | ||
| não código-fonte. | ||
|
|
||
| ## Verificação | ||
|
|
||
| Antes de abrir PR, rode o que estiver disponível: | ||
|
|
||
| ```powershell | ||
| python python/verify_research.py | ||
| python -m pytest python/tests -q | ||
| julia --project=julia julia/smoke_test.jl | ||
| ``` | ||
|
|
||
| Se Julia não estiver disponível localmente, não declare a alteração validada | ||
| somente por inspeção: publique a branch e aguarde o GitHub Actions concluir. | ||
| Não inicie treino, RLAIF ou chamadas externas como parte da verificação. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # Configuração para experimentos e ablações baratos. | ||
| # Mantém tokenizer, dados e sequência da baseline de 45M; reduz apenas capacidade. | ||
|
|
||
| [model] | ||
| name = "cafune-mini-7m" | ||
| vocab_size = 1999 | ||
| seq_len = 128 | ||
| d_model = 256 | ||
| n_heads = 8 | ||
| n_layers = 8 | ||
| d_ff = 1024 | ||
| dropout = 0.1 | ||
| linear_mode = "float32" | ||
|
|
||
| [tokenizer] | ||
| type = "sentencepiece_bpe" | ||
| model = "python/cafune_spm.model" | ||
| vocab = "python/vocab_spm.json" | ||
| config = "python/spm_config.json" | ||
| dataset = "python/dataset_tokens.json" | ||
| pad_id = 0 | ||
| unk_id = 1 | ||
| bos_id = 2 | ||
| eos_id = 3 | ||
| mask_id = 4 | ||
|
|
||
| [data] | ||
| splits = "python/dataset_splits.json" | ||
| train_ratio = 0.90 | ||
| validation_ratio = 0.05 | ||
| test_ratio = 0.05 | ||
| split_seed = "cafune-v1" | ||
|
|
||
| [experiment] | ||
| purpose = "cheap_architecture_and_tokenizer_ablations" | ||
| parameters = 7071744 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Registro de experimentos | ||
|
|
||
| Este arquivo preserva a trilha científica do CAFUNE. Registre uma entrada antes | ||
| de iniciar qualquer treino que produza resultado comparável. | ||
|
|
||
| Cada entrada deve declarar hipótese, configuração, dados/splits, sementes, | ||
| métrica de decisão, estado e links para artefatos. Não promova uma hipótese a | ||
| conclusão sem um relatório de avaliação reproduzível. | ||
|
|
||
| ## EXP-001 — CAFUNE-mini como bancada de ablações | ||
|
|
||
| - **Hipótese:** uma configuração de aproximadamente 7M parâmetros permite | ||
| comparar escolhas arquiteturais antes de escalar para o modelo canônico de | ||
| 45M. | ||
| - **Branch:** `feature/cafune-mini`. | ||
| - **Configuração:** `config/experiments/cafune-mini.toml` — 8 camadas, | ||
| `d_model=256`, 8 heads, `d_ff=1024`, 7.071.744 parâmetros. | ||
| - **Controles:** SentencePiece BPE 1.999, `seq_len=128`, | ||
| `python/dataset_tokens.json` e `python/dataset_splits.json` idênticos à | ||
| baseline canônica. | ||
| - **Métrica de decisão:** `aggregate.loss_mean` no split de validação, com | ||
| máscaras em 0,10 / 0,25 / 0,50 / 0,75 / 0,90 e três seeds. | ||
| - **Estado:** pronto para treino; sanity training e CI passaram. Ainda não há | ||
| métrica de qualidade ou conclusão empírica. | ||
| - **Próxima comparação:** MHA-only versus MHA+SSA, com esta configuração e os | ||
| mesmos controles. | ||
|
|
||
| ## Convenções de artefatos | ||
|
|
||
| - Checkpoints: `julia/checkpoints/<experimento>/`. | ||
| - Avaliações: `julia/evaluations/`; preserve no JSON a configuração, checkpoint, | ||
| split, hash do dataset e seeds. | ||
| - Resultados agregados e interpretação entram neste arquivo após confirmação de | ||
| reprodutibilidade. Logs brutos não pertencem ao Git. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -92,16 +92,27 @@ const SCRIPT_DIR = @__DIR__ | |
| const SANITY_MODE = "--sanity" in ARGS | ||
| const BITNET_MODE = "--bitnet" in ARGS | ||
| const RLAIF_MODE = "--rlaif" in ARGS | ||
| const RESEARCH_CONFIG = normpath(joinpath(SCRIPT_DIR, "..", "config", "research.toml")) | ||
| const DEFAULT_RESEARCH_CONFIG = normpath(joinpath(SCRIPT_DIR, "..", "config", "research.toml")) | ||
| const RESEARCH_CONFIG = let index = findfirst(==("--config"), ARGS) | ||
| if index === nothing | ||
| DEFAULT_RESEARCH_CONFIG | ||
| else | ||
| index < length(ARGS) || error("--config requer um caminho para um arquivo TOML.") | ||
| config_path = ARGS[index + 1] | ||
| normpath(isabspath(config_path) ? config_path : joinpath(pwd(), config_path)) | ||
|
Comment on lines
+101
to
+102
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a tokenizer or dataset ablation is passed through AGENTS.md reference: AGENTS.md:L20-L23 Useful? React with 👍 / 👎. |
||
| end | ||
| end | ||
| const EXPERIMENT_NAME = RESEARCH_CONFIG == DEFAULT_RESEARCH_CONFIG ? "baseline" : splitext(basename(RESEARCH_CONFIG))[1] | ||
| const MEM_FILE = normpath(joinpath(SCRIPT_DIR, "..", "cafune_brain.mem")) | ||
| const CORPUS_FILE = normpath(joinpath(SCRIPT_DIR, "..", "python", "social_data.json")) | ||
| const VOCAB_FILE = normpath(joinpath(SCRIPT_DIR, "..", "vocab.json")) | ||
| const SPM_CONFIG = normpath(joinpath(SCRIPT_DIR, "..", "python", "spm_config.json")) | ||
| const SPM_TOKENS = normpath(joinpath(SCRIPT_DIR, "..", "python", "dataset_tokens.json")) | ||
| const DATA_SPLITS = normpath(joinpath(SCRIPT_DIR, "..", "python", "dataset_splits.json")) | ||
| const VARIANT_DIR = BITNET_MODE ? "bitnet" : "baseline" | ||
| const CKPT_DIR = BITNET_MODE ? joinpath(SCRIPT_DIR, "checkpoints", SANITY_MODE ? "sanity" : "", "bitnet") : | ||
| (SANITY_MODE ? joinpath(SCRIPT_DIR, "checkpoints", "sanity") : joinpath(SCRIPT_DIR, "checkpoints")) | ||
| const VARIANT_DIR = BITNET_MODE ? "bitnet" : EXPERIMENT_NAME | ||
| const CKPT_DIR = BITNET_MODE ? joinpath(SCRIPT_DIR, "checkpoints", SANITY_MODE ? "sanity" : "", EXPERIMENT_NAME, "bitnet") : | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
With the default config and Useful? React with 👍 / 👎. |
||
| SANITY_MODE ? (EXPERIMENT_NAME == "baseline" ? joinpath(SCRIPT_DIR, "checkpoints", "sanity") : joinpath(SCRIPT_DIR, "checkpoints", "sanity", EXPERIMENT_NAME)) : | ||
| EXPERIMENT_NAME == "baseline" ? joinpath(SCRIPT_DIR, "checkpoints") : joinpath(SCRIPT_DIR, "checkpoints", EXPERIMENT_NAME) | ||
|
Comment on lines
+114
to
+115
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Although custom checkpoints are routed into an experiment-specific directory here, every non-sanity run still appends to the shared Useful? React with 👍 / 👎. |
||
| const BEST_CKPT = joinpath(CKPT_DIR, "cafune_best.bson") | ||
| const TRAIN_LOG = SANITY_MODE ? joinpath(CKPT_DIR, "training_log.jsonl") : joinpath(SCRIPT_DIR, "training_log.jsonl") | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every push and pull-request verification now invokes
main_training.jl --sanity; that path callstrain!, performs optimizer updates, evaluates the result, and writes checkpoints rather than merely checking syntax or a forward/backward primitive. This directly turns CI verification into a training run despite the repository's explicit verification contract.AGENTS.md reference: AGENTS.md:L44-L44
Useful? React with 👍 / 👎.