attacklm 0.7.0__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {attacklm-0.7.0 → attacklm-0.8.0}/CHANGELOG.md +51 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/PKG-INFO +76 -22
- {attacklm-0.7.0 → attacklm-0.8.0}/README.md +75 -21
- attacklm-0.8.0/attacklm-gui/README.md +145 -0
- attacklm-0.8.0/attacklm-gui/pyproject.toml +19 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/__init__.py +3 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/app.py +58 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/cli.py +17 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/presets.py +170 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/runner.py +223 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/screens/__init__.py +1 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/screens/command_forms.py +353 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/screens/main_menu.py +91 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/screens/train_form.py +451 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/screens/train_live.py +328 -0
- attacklm-0.8.0/attacklm-gui/src/attacklm_gui/widgets/__init__.py +1 -0
- attacklm-0.8.0/attacklm-gui/tests/test_gui.py +208 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/README.md +4 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/pyproject.toml +11 -2
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/device_utils.py +34 -1
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/train_template.py +186 -7
- attacklm-0.8.0/src/attacklm/__version__.py +1 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/src/attacklm/_project_root.py +1 -1
- attacklm-0.8.0/src/attacklm/cli.py +636 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_init_pipeline.py +2 -2
- attacklm-0.7.0/src/attacklm/__version__.py +0 -1
- attacklm-0.7.0/src/attacklm/cli.py +0 -236
- {attacklm-0.7.0 → attacklm-0.8.0}/.github/workflows/release.yml +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/.gitignore +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/ATTRIBUTION.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/CONTRIBUTING.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/EVALUATION.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/LICENSE +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/MANIFEST.in +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/Makefile +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/NOTICE +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/QA_BEFORE_RELEASES.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/REPLAY_PLAN.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/ATTRIBUTION.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/LEGAL.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/REMOVAL.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/bench/questions.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/bench/speed_context.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/ATTRIBUTION.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/GEMINI_RESEARCH_2026-06-11.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/acquisition_report.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/manifest.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/README.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/_index.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/base/collection/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/base/discovery/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/base/execution/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/atomic-red-team/base/persistence/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/attacklm-synthetic/orchestrator/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/azure-pyrit/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/azure-pyrit/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/cyberark-fuzzyai/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/cyberark-fuzzyai/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/elastic-rules/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/elastic-rules/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/elastic-rules/defensive/detection_engineering/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/cloud/attacks/data_llm.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/ics/attacks/data_llm.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/social_engineering/phishing/data_llm.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/llm-generated/wireless/attacks/data_llm.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/collection/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/credential_access/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/defense_evasion/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/discovery/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/execution/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/lateral_movement/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/persistence/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/base/privilege_escalation/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/metasploit-framework/tools/metasploit/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-atlas-arsenal/base/discovery/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/base/collection/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/base/discovery/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/base/execution/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mitre-stockpile/base/persistence/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mordor/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mordor/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/mordor/defensive/threat_hunting/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nist-ir/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nist-ir/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nist-ir/defensive/incident_response/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nvidia-garak/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nvidia-garak/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/nvidia-garak/ai/jailbreaking/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptfoo/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptfoo/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptfoo/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptmap/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptmap/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/promptmap/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/base/replay/data_code.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/base/replay/data_conversation.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/base/replay/data_factual.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/replay-general/base/replay/data_reasoning.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/sigma-hq/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/sigma-hq/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/sigma-hq/defensive/detection_engineering/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/splunk-content/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/splunk-content/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/splunk-content/defensive/detection_engineering/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/datasets/buckets/sources/threathunter-playbook/defensive/threat_hunting/data.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/golden/prompts.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/reference/prompts.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/steering/prompts/opsec_aware.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/steering/prompts/opsec_unaware.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/steering/prompts/succinct.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/data/steering/prompts/verbose.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/experiments/README.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/experiments/synthetic_dataset_mutator_evol_instruct.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/.gitattributes +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/data/manifest.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/dataset_infos.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/scripts/build_hf_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hf/scripts/push_to_hf.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hpo_runs/.gitkeep +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hpo_runs/hpo_state.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/hpo_runs/hpo_trial_dataset.jsonl +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/logs/.gitkeep +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/notes/BLUE_TEAM_DESIGN_v0.5.0.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/notes/EVAL_DESIGN_v0.4.0.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/notes/STEERING_REVIEW_v0.4.0.md +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/pipeline.example.yaml +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/presets/blue-team.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/presets/purple-team.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/presets/red-team.json +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/requirements.txt +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/_eval_loader.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_cloud_attack_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_ics_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_phishing_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_red_team_tactics.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_replay_general.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_supply_chain_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_web_attack_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/acquire_wireless_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/audit_dataset.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/balance_buckets.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/bucket_loader.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/build.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/clone_repos.sh +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/collect_reference.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/compare_scores.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/convert_to_gguf.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/demo.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/domain_bench.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/eval_retention.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_ai_tools_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_atomic_red_team_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_by_tactic.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_caldera_plugins_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_elastic_rules.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_infection_monkey_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_mordor.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_nist_ir.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_rta_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_sigma_defensive.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_splunk_content.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/extract_threathunter_playbook.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/generate_synthetic_scarce.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/golden_vectors.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/hpo_runner.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/import_gguf.sh +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/import_to_lmstudio.sh +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/infer.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/init_pipeline.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/merge_adapter.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/mitre_tactic_lookup.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/parse_metasploit_to_jsonl.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/pipeline.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/rebuild_manifest.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/register_ollama.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/reorganize_buckets.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/replay_mixer.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/score_candidates.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/setup_buckets.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/speed_bench.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/steering.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/scripts/train_all.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/src/attacklm/__init__.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_balance_buckets.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_collect_reference.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_compare_scores.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_domain_bench.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_eval_loader.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_eval_retention.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_golden_vectors.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_replay_mixer.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_score_candidates.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_speed_bench.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_steering.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/tests/test_thinking_models.py +0 -0
- {attacklm-0.7.0 → attacklm-0.8.0}/uv.lock +0 -0
|
@@ -4,6 +4,57 @@ All notable changes to AttackLM are documented in this file. Versions follow [Se
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.8.0] — 2026-06-30 — Unified CLI with subcommands
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **Unified CLI**: New `attacklm` command with argparse subcommands replaces 21 hyphenated commands
|
|
11
|
+
- `attacklm train [--dataset all] [--hpo]` — consolidates `attacklm-train`, `attacklm-train-all`, `attacklm-train-lora`, `attacklm-hpo`
|
|
12
|
+
- `attacklm init [--extract-only|--buckets-only|--attribute-only|--clone-only]` — consolidates `attacklm-init`, `attacklm-extract`, `attacklm-buckets`, `attacklm-attribute`, `attacklm-clone`
|
|
13
|
+
- `attacklm build [--merge-only|--gguf-only|--register-ollama]` — consolidates `attacklm-build`, `attacklm-merge`, `attacklm-gguf`, `attacklm-register-ollama`
|
|
14
|
+
- `attacklm eval [--collect-ref|--score|--compare|--golden]` — consolidates `attacklm-eval`, `attacklm-collect-ref`, `attacklm-score`, `attacklm-compare`, `attacklm-golden`
|
|
15
|
+
- `attacklm balance` — replaces `attacklm-balance`
|
|
16
|
+
- `attacklm infer` — replaces `attacklm-infer`
|
|
17
|
+
- `attacklm gui` — replaces `attacklm-gui`
|
|
18
|
+
- `attacklm demo` — replaces `attacklm-demo`
|
|
19
|
+
- **`attacklm --version`**: Shows version number
|
|
20
|
+
- **Evaluation screen in GUI**: New `EvalFormScreen` with buttons for all eval subcommands (Retention, Collect Ref, Score, Compare, Golden)
|
|
21
|
+
- **Build screen in GUI**: Consolidated buttons for Full Build, Merge Only, GGUF Only
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **GUI main menu**: Consolidated from 8 buttons to 6 (Train, Init, Balance, Build, Infer, Eval) — removed separate Extract/Merge/Pipeline buttons
|
|
25
|
+
- **GUI train form**: Now calls `attacklm train` instead of `attacklm-train`
|
|
26
|
+
- **GUI command forms**: All commands now use `attacklm <subcommand>` format instead of `attacklm-<command>`
|
|
27
|
+
- **Deprecation warnings**: All old hyphenated commands print a deprecation notice before delegating to the new subcommand
|
|
28
|
+
|
|
29
|
+
### Deprecated
|
|
30
|
+
- All 21 hyphenated commands (`attacklm-train`, `attacklm-train-all`, etc.) still work but print deprecation warnings. They will be removed in v0.9.0.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [0.7.1] — 2026-06-30 — GUI, VRAM fixes, dataset caching
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- **attacklm-gui**: Terminal-based TUI wrapper (Textual) for all CLI commands
|
|
38
|
+
- Form-based training config with 40+ params in 5 tabs (Basic, LoRA, GaLore, Advanced, Hardware)
|
|
39
|
+
- Live training monitor with loss sparkline, VRAM gauge, progress bar, log viewer
|
|
40
|
+
- One-click screens for extract, balance, infer, merge, build, pipeline, init
|
|
41
|
+
- 5 built-in presets (3B Q-GaLore, 3B LoRA, 7B Q-GaLore, 7B QLoRA, etc.)
|
|
42
|
+
- Pause/resume/quit controls during training
|
|
43
|
+
- Works in terminal-only environments (no X11/WSLg required)
|
|
44
|
+
- **Dataset caching**: Tokenized datasets saved to disk after first run, reloaded in ~1s on subsequent runs (keyed by dataset + model + max_length + packing)
|
|
45
|
+
- **config.json fix**: Training runs now preserve HF model architecture fields (model_type, architectures, hidden_size, etc.) for GGUF conversion compatibility
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- **VRAM fragmentation**: Removed `device_map="auto"` for single-GPU training — was splitting model across GPU+CPU, creating meta tensors, and leaving VRAM fragmented. Model now loads directly to GPU.
|
|
49
|
+
- **Spectrum crash on 7B**: Skip meta-device tensors in SNR computation (caused by CPU-offloaded layers from device_map="auto")
|
|
50
|
+
- **VRAM parsing**: Added regex for compact VRAM format (`VRAM X/Y GB (A alloc + C cache)`) in training output parser
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- Moved attacklm-gui into the main AttackLM repo under `attacklm-gui/`
|
|
54
|
+
- 17 GUI tests passing
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
7
58
|
## [0.7.0] — 2026-06-29 — Defensive data extraction, test fixes, script cleanup
|
|
8
59
|
|
|
9
60
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: attacklm
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: QLoRA-fine-tuned Qwen2.5-Coder for offensive/defensive security and AI red-teaming
|
|
5
5
|
Project-URL: Homepage, https://github.com/Veedubin/AttackLM
|
|
6
6
|
Project-URL: Repository, https://github.com/Veedubin/AttackLM
|
|
@@ -205,6 +205,27 @@ AttackLM — QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded security AI
|
|
|
205
205
|
|
|
206
206
|
---
|
|
207
207
|
|
|
208
|
+
## GUI (New in v0.7.1)
|
|
209
|
+
|
|
210
|
+
AttackLM now includes a terminal-based GUI for all commands. No more memorizing 40+ CLI flags.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
pip install attacklm-gui
|
|
214
|
+
attacklm-gui
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Features:
|
|
218
|
+
- **Training form** with 40+ params in 5 tabs (Basic, LoRA, GaLore, Advanced, Hardware)
|
|
219
|
+
- **Live training monitor** with loss sparkline, VRAM gauge, progress bar, and log viewer
|
|
220
|
+
- **One-click screens** for extract, balance, infer, merge, build, pipeline, and init
|
|
221
|
+
- **5 built-in presets** (3B Q-GaLore, 3B LoRA, 7B Q-GaLore, 7B QLoRA, etc.)
|
|
222
|
+
- **Pause/resume/quit** controls during training
|
|
223
|
+
- Works in **terminal-only** environments — no X11, no browser, no GPU required. Works over SSH and WSL.
|
|
224
|
+
|
|
225
|
+
The CLI still works exactly as before. The GUI is a thin wrapper that constructs and runs CLI commands.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
208
229
|
## Install
|
|
209
230
|
The recommended way to install the full CUDA training stack:
|
|
210
231
|
|
|
@@ -346,29 +367,62 @@ This layout allows the pipeline to deterministically extract data from upstream
|
|
|
346
367
|
---
|
|
347
368
|
|
|
348
369
|
## CLI Reference
|
|
370
|
+
|
|
371
|
+
> **v0.8.0**: The 21 hyphenated commands are consolidated into a single
|
|
372
|
+
> `attacklm` command with subcommands. The old commands still work but
|
|
373
|
+
> print a deprecation warning. They will be removed in v0.9.0.
|
|
374
|
+
|
|
375
|
+
### Unified Command (v0.8.0+)
|
|
376
|
+
|
|
349
377
|
| Command | Description |
|
|
350
378
|
|---------|-------------|
|
|
351
|
-
| `attacklm
|
|
352
|
-
| `attacklm
|
|
353
|
-
| `attacklm
|
|
354
|
-
| `attacklm
|
|
355
|
-
| `attacklm-
|
|
356
|
-
| `attacklm-
|
|
357
|
-
| `attacklm-
|
|
358
|
-
| `attacklm-
|
|
359
|
-
| `attacklm
|
|
360
|
-
| `attacklm
|
|
361
|
-
| `attacklm-
|
|
362
|
-
| `attacklm-
|
|
363
|
-
| `attacklm-
|
|
364
|
-
| `attacklm
|
|
365
|
-
| `attacklm
|
|
366
|
-
| `attacklm-
|
|
367
|
-
| `attacklm
|
|
368
|
-
| `attacklm
|
|
369
|
-
| `attacklm
|
|
370
|
-
| `attacklm
|
|
371
|
-
| `attacklm
|
|
379
|
+
| `attacklm train` | Train a model (QLoRA, GaLore, Q-GaLore, Spectrum, PiSSA) |
|
|
380
|
+
| `attacklm train --dataset all` | Train all buckets (replaces `attacklm-train-all`) |
|
|
381
|
+
| `attacklm train --hpo` | Run HPO sweep (replaces `attacklm-hpo`) |
|
|
382
|
+
| `attacklm init` | One-shot init: clone → extract → attribute → buckets |
|
|
383
|
+
| `attacklm init --extract-only` | Extract data only (replaces `attacklm-extract`) |
|
|
384
|
+
| `attacklm init --buckets-only` | Organize into buckets only (replaces `attacklm-buckets`) |
|
|
385
|
+
| `attacklm init --attribute-only` | Add attribution only (replaces `attacklm-attribute`) |
|
|
386
|
+
| `attacklm init --clone-only` | Clone repos only (replaces `attacklm-clone`) |
|
|
387
|
+
| `attacklm balance` | Build a balanced subset of buckets |
|
|
388
|
+
| `attacklm build` | One-shot merge → GGUF → install to LM Studio |
|
|
389
|
+
| `attacklm build --merge-only` | Merge adapter only (replaces `attacklm-merge`) |
|
|
390
|
+
| `attacklm build --gguf-only` | Convert to GGUF only (replaces `attacklm-gguf`) |
|
|
391
|
+
| `attacklm build --register-ollama` | Register GGUF with Ollama (replaces `attacklm-register-ollama`) |
|
|
392
|
+
| `attacklm infer` | Smoke-test inference |
|
|
393
|
+
| `attacklm eval` | Run retention evaluation suite |
|
|
394
|
+
| `attacklm eval --collect-ref` | Collect reference model outputs |
|
|
395
|
+
| `attacklm eval --score` | Score candidate models against reference |
|
|
396
|
+
| `attacklm eval --compare` | Compare multiple candidate model scores |
|
|
397
|
+
| `attacklm eval --golden` | Execute golden vector regression gates |
|
|
398
|
+
| `attacklm gui` | Terminal GUI for all commands |
|
|
399
|
+
| `attacklm demo` | Multi-agent orchestrator demo |
|
|
400
|
+
|
|
401
|
+
### Legacy Commands (Deprecated, removed in v0.9.0)
|
|
402
|
+
|
|
403
|
+
| Old Command | New Command |
|
|
404
|
+
|-------------|-------------|
|
|
405
|
+
| `attacklm-train` | `attacklm train` |
|
|
406
|
+
| `attacklm-train-all` | `attacklm train --dataset all` |
|
|
407
|
+
| `attacklm-train-lora` | `attacklm train` |
|
|
408
|
+
| `attacklm-hpo` | `attacklm train --hpo` |
|
|
409
|
+
| `attacklm-init` | `attacklm init` |
|
|
410
|
+
| `attacklm-extract` | `attacklm init --extract-only` |
|
|
411
|
+
| `attacklm-buckets` | `attacklm init --buckets-only` |
|
|
412
|
+
| `attacklm-attribute` | `attacklm init --attribute-only` |
|
|
413
|
+
| `attacklm-clone` | `attacklm init --clone-only` |
|
|
414
|
+
| `attacklm-balance` | `attacklm balance` |
|
|
415
|
+
| `attacklm-build` | `attacklm build` |
|
|
416
|
+
| `attacklm-merge` | `attacklm build --merge-only` |
|
|
417
|
+
| `attacklm-gguf` | `attacklm build --gguf-only` |
|
|
418
|
+
| `attacklm-register-ollama` | `attacklm build --register-ollama` |
|
|
419
|
+
| `attacklm-infer` | `attacklm infer` |
|
|
420
|
+
| `attacklm-eval` | `attacklm eval` |
|
|
421
|
+
| `attacklm-collect-ref` | `attacklm eval --collect-ref` |
|
|
422
|
+
| `attacklm-score` | `attacklm eval --score` |
|
|
423
|
+
| `attacklm-compare` | `attacklm eval --compare` |
|
|
424
|
+
| `attacklm-golden` | `attacklm eval --golden` |
|
|
425
|
+
| `attacklm-demo` | `attacklm demo` |
|
|
372
426
|
|
|
373
427
|
---
|
|
374
428
|
|
|
@@ -7,6 +7,27 @@ AttackLM — QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded security AI
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## GUI (New in v0.7.1)
|
|
11
|
+
|
|
12
|
+
AttackLM now includes a terminal-based GUI for all commands. No more memorizing 40+ CLI flags.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install attacklm-gui
|
|
16
|
+
attacklm-gui
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Features:
|
|
20
|
+
- **Training form** with 40+ params in 5 tabs (Basic, LoRA, GaLore, Advanced, Hardware)
|
|
21
|
+
- **Live training monitor** with loss sparkline, VRAM gauge, progress bar, and log viewer
|
|
22
|
+
- **One-click screens** for extract, balance, infer, merge, build, pipeline, and init
|
|
23
|
+
- **5 built-in presets** (3B Q-GaLore, 3B LoRA, 7B Q-GaLore, 7B QLoRA, etc.)
|
|
24
|
+
- **Pause/resume/quit** controls during training
|
|
25
|
+
- Works in **terminal-only** environments — no X11, no browser, no GPU required. Works over SSH and WSL.
|
|
26
|
+
|
|
27
|
+
The CLI still works exactly as before. The GUI is a thin wrapper that constructs and runs CLI commands.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
10
31
|
## Install
|
|
11
32
|
The recommended way to install the full CUDA training stack:
|
|
12
33
|
|
|
@@ -148,29 +169,62 @@ This layout allows the pipeline to deterministically extract data from upstream
|
|
|
148
169
|
---
|
|
149
170
|
|
|
150
171
|
## CLI Reference
|
|
172
|
+
|
|
173
|
+
> **v0.8.0**: The 21 hyphenated commands are consolidated into a single
|
|
174
|
+
> `attacklm` command with subcommands. The old commands still work but
|
|
175
|
+
> print a deprecation warning. They will be removed in v0.9.0.
|
|
176
|
+
|
|
177
|
+
### Unified Command (v0.8.0+)
|
|
178
|
+
|
|
151
179
|
| Command | Description |
|
|
152
180
|
|---------|-------------|
|
|
153
|
-
| `attacklm
|
|
154
|
-
| `attacklm
|
|
155
|
-
| `attacklm
|
|
156
|
-
| `attacklm
|
|
157
|
-
| `attacklm-
|
|
158
|
-
| `attacklm-
|
|
159
|
-
| `attacklm-
|
|
160
|
-
| `attacklm-
|
|
161
|
-
| `attacklm
|
|
162
|
-
| `attacklm
|
|
163
|
-
| `attacklm-
|
|
164
|
-
| `attacklm-
|
|
165
|
-
| `attacklm-
|
|
166
|
-
| `attacklm
|
|
167
|
-
| `attacklm
|
|
168
|
-
| `attacklm-
|
|
169
|
-
| `attacklm
|
|
170
|
-
| `attacklm
|
|
171
|
-
| `attacklm
|
|
172
|
-
| `attacklm
|
|
173
|
-
| `attacklm
|
|
181
|
+
| `attacklm train` | Train a model (QLoRA, GaLore, Q-GaLore, Spectrum, PiSSA) |
|
|
182
|
+
| `attacklm train --dataset all` | Train all buckets (replaces `attacklm-train-all`) |
|
|
183
|
+
| `attacklm train --hpo` | Run HPO sweep (replaces `attacklm-hpo`) |
|
|
184
|
+
| `attacklm init` | One-shot init: clone → extract → attribute → buckets |
|
|
185
|
+
| `attacklm init --extract-only` | Extract data only (replaces `attacklm-extract`) |
|
|
186
|
+
| `attacklm init --buckets-only` | Organize into buckets only (replaces `attacklm-buckets`) |
|
|
187
|
+
| `attacklm init --attribute-only` | Add attribution only (replaces `attacklm-attribute`) |
|
|
188
|
+
| `attacklm init --clone-only` | Clone repos only (replaces `attacklm-clone`) |
|
|
189
|
+
| `attacklm balance` | Build a balanced subset of buckets |
|
|
190
|
+
| `attacklm build` | One-shot merge → GGUF → install to LM Studio |
|
|
191
|
+
| `attacklm build --merge-only` | Merge adapter only (replaces `attacklm-merge`) |
|
|
192
|
+
| `attacklm build --gguf-only` | Convert to GGUF only (replaces `attacklm-gguf`) |
|
|
193
|
+
| `attacklm build --register-ollama` | Register GGUF with Ollama (replaces `attacklm-register-ollama`) |
|
|
194
|
+
| `attacklm infer` | Smoke-test inference |
|
|
195
|
+
| `attacklm eval` | Run retention evaluation suite |
|
|
196
|
+
| `attacklm eval --collect-ref` | Collect reference model outputs |
|
|
197
|
+
| `attacklm eval --score` | Score candidate models against reference |
|
|
198
|
+
| `attacklm eval --compare` | Compare multiple candidate model scores |
|
|
199
|
+
| `attacklm eval --golden` | Execute golden vector regression gates |
|
|
200
|
+
| `attacklm gui` | Terminal GUI for all commands |
|
|
201
|
+
| `attacklm demo` | Multi-agent orchestrator demo |
|
|
202
|
+
|
|
203
|
+
### Legacy Commands (Deprecated, removed in v0.9.0)
|
|
204
|
+
|
|
205
|
+
| Old Command | New Command |
|
|
206
|
+
|-------------|-------------|
|
|
207
|
+
| `attacklm-train` | `attacklm train` |
|
|
208
|
+
| `attacklm-train-all` | `attacklm train --dataset all` |
|
|
209
|
+
| `attacklm-train-lora` | `attacklm train` |
|
|
210
|
+
| `attacklm-hpo` | `attacklm train --hpo` |
|
|
211
|
+
| `attacklm-init` | `attacklm init` |
|
|
212
|
+
| `attacklm-extract` | `attacklm init --extract-only` |
|
|
213
|
+
| `attacklm-buckets` | `attacklm init --buckets-only` |
|
|
214
|
+
| `attacklm-attribute` | `attacklm init --attribute-only` |
|
|
215
|
+
| `attacklm-clone` | `attacklm init --clone-only` |
|
|
216
|
+
| `attacklm-balance` | `attacklm balance` |
|
|
217
|
+
| `attacklm-build` | `attacklm build` |
|
|
218
|
+
| `attacklm-merge` | `attacklm build --merge-only` |
|
|
219
|
+
| `attacklm-gguf` | `attacklm build --gguf-only` |
|
|
220
|
+
| `attacklm-register-ollama` | `attacklm build --register-ollama` |
|
|
221
|
+
| `attacklm-infer` | `attacklm infer` |
|
|
222
|
+
| `attacklm-eval` | `attacklm eval` |
|
|
223
|
+
| `attacklm-collect-ref` | `attacklm eval --collect-ref` |
|
|
224
|
+
| `attacklm-score` | `attacklm eval --score` |
|
|
225
|
+
| `attacklm-compare` | `attacklm eval --compare` |
|
|
226
|
+
| `attacklm-golden` | `attacklm eval --golden` |
|
|
227
|
+
| `attacklm-demo` | `attacklm demo` |
|
|
174
228
|
|
|
175
229
|
---
|
|
176
230
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# AttackLM GUI
|
|
2
|
+
|
|
3
|
+
Terminal-based GUI wrapper for the [AttackLM](https://github.com/Veedubin/AttackLM) CLI training tools. Built with [Textual](https://textual.textualize.io/).
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
AttackLM has a unified CLI (`attacklm train`, `attacklm init`, etc.) with 8 subcommands. `attacklm train` alone has 40+ parameters. Remembering all the flags is painful. The GUI provides:
|
|
8
|
+
|
|
9
|
+
- **Form-based parameter input** with tabs, presets, and validation
|
|
10
|
+
- **Live training monitoring** with loss charts, VRAM gauges, and log streaming
|
|
11
|
+
- **One-click commands** for extract, balance, infer, merge, build, and more
|
|
12
|
+
- **Works everywhere** — terminal-only, no X11 required (WSL, SSH, headless)
|
|
13
|
+
|
|
14
|
+
The unified CLI (`attacklm <subcommand>`) still works as before. The GUI is a thin wrapper that constructs and runs CLI commands.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install attacklm-gui
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or from source:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/Veedubin/AttackLM.git
|
|
26
|
+
cd AttackLM-Models/attacklm-gui
|
|
27
|
+
pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Requires `attacklm` (the CLI package) and `textual>=2.0`.
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
attacklm-gui
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Main Menu
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
┌──────────────────────────────────────┐
|
|
42
|
+
│ AttackLM GUI v0.1.0 │
|
|
43
|
+
│ │
|
|
44
|
+
│ 🏋️ Train Model │
|
|
45
|
+
│ 🚀 Init Dataset │
|
|
46
|
+
│ ⚖️ Balance Dataset │
|
|
47
|
+
│ 📦 Build & Install │
|
|
48
|
+
│ 🧠 Run Inference │
|
|
49
|
+
│ 📊 Evaluate │
|
|
50
|
+
└──────────────────────────────────────┘
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Training Form
|
|
54
|
+
|
|
55
|
+
The training form organizes 40+ parameters into tabs:
|
|
56
|
+
|
|
57
|
+
| Tab | Parameters |
|
|
58
|
+
|-----|-----------|
|
|
59
|
+
| **Basic** | dataset, output, base model, epochs, batch size, max length |
|
|
60
|
+
| **LoRA** | rank, alpha, dropout, DoRA, RSLoRA, target modules, PiSSA |
|
|
61
|
+
| **GaLore** | Q-GaLore, rank, 32-bit, Spectrum layer freezing |
|
|
62
|
+
| **Advanced** | eval split, early stopping, save steps, gradient accum, optimizer, packing, live LR |
|
|
63
|
+
| **Hardware** | precision (BF16/FP16/FP32), multi-GPU, MoE safe, auto-tune |
|
|
64
|
+
|
|
65
|
+
**Presets** save and load complete configurations. Built-in presets:
|
|
66
|
+
- `3B Q-GaLore Spectrum` — full-parameter training on 16GB GPU
|
|
67
|
+
- `3B Q-GaLore Rank 128` — higher quality variant
|
|
68
|
+
- `3B LoRA Default` — standard QLoRA
|
|
69
|
+
- `7B Q-GaLore` — for 24GB GPUs
|
|
70
|
+
- `7B QLoRA Default` — standard QLoRA for 7B
|
|
71
|
+
|
|
72
|
+
### Live Training Monitor
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
┌─────────────────────────────────────────────────────┐
|
|
76
|
+
│ Training: attacklm-3b-qgalore-spectrum │
|
|
77
|
+
│ Epoch 12/30 | Step 1896 | Elapsed: 1h 23m │
|
|
78
|
+
├──────────────────────┬──────────────────────────────┤
|
|
79
|
+
│ Loss: 1.1143 ▂▃▅▆▇ │ VRAM: 5.9/15.6 GB (62%) │
|
|
80
|
+
│ Eval Loss: 1.176 │ alloc: 5.9 cache: 4.8 │
|
|
81
|
+
│ Trend: ↓ -0.0116 │ ████████░░░░ │
|
|
82
|
+
├──────────────────────┴──────────────────────────────┤
|
|
83
|
+
│ Log Output (scrolling) │
|
|
84
|
+
│ Epoch 12/20 58% | loss 1.1143 | 2,844 tok/s ... │
|
|
85
|
+
├─────────────────────────────────────────────────────┤
|
|
86
|
+
│ [P]ause [S]top at checkpoint [Q]uit │
|
|
87
|
+
└─────────────────────────────────────────────────────┘
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Controls:
|
|
91
|
+
- **Pause/Resume** — SIGSTOP/SIGCONT the training process
|
|
92
|
+
- **Stop at Checkpoint** — graceful stop after current eval
|
|
93
|
+
- **Quit** — kill training immediately
|
|
94
|
+
|
|
95
|
+
### Other Commands
|
|
96
|
+
|
|
97
|
+
| Screen | What it does |
|
|
98
|
+
|--------|-------------|
|
|
99
|
+
| **Init** | Clone repos, extract data, organize buckets |
|
|
100
|
+
| **Balance** | Balance a dataset with cap size |
|
|
101
|
+
| **Inference** | Run a trained model with a prompt |
|
|
102
|
+
| **Build** | Merge → GGUF → install to LM Studio |
|
|
103
|
+
| **Eval** | Retention eval, collect-ref, score, compare, golden |
|
|
104
|
+
| **Pipeline** | Run a YAML training pipeline |
|
|
105
|
+
|
|
106
|
+
## Keyboard Shortcuts
|
|
107
|
+
|
|
108
|
+
| Key | Action |
|
|
109
|
+
|-----|--------|
|
|
110
|
+
| `q` | Quit |
|
|
111
|
+
| `m` | Return to main menu |
|
|
112
|
+
| `Tab` | Next field |
|
|
113
|
+
| `Enter` | Activate button |
|
|
114
|
+
| `Esc` | Go back |
|
|
115
|
+
|
|
116
|
+
## Architecture
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
attacklm-gui/
|
|
120
|
+
├── src/attacklm_gui/
|
|
121
|
+
│ ├── app.py # Textual App entry point
|
|
122
|
+
│ ├── cli.py # CLI entry point
|
|
123
|
+
│ ├── runner.py # Subprocess manager + output parser
|
|
124
|
+
│ ├── presets.py # Save/load training presets
|
|
125
|
+
│ ├── screens/
|
|
126
|
+
│ │ ├── main_menu.py # Command launcher (6 buttons)
|
|
127
|
+
│ │ ├── train_form.py # Training parameter form
|
|
128
|
+
│ │ ├── train_live.py # Live training monitor
|
|
129
|
+
│ │ └── command_forms.py # Init, Balance, Infer, Build, Eval, Pipeline screens
|
|
130
|
+
│ └── widgets/
|
|
131
|
+
│ └── __init__.py
|
|
132
|
+
└── tests/
|
|
133
|
+
└── test_gui.py
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The GUI never touches AttackLM's internal logic. It constructs CLI command strings and runs them via `asyncio.create_subprocess_exec`. All training, extraction, and inference logic stays in `scripts/*.py`.
|
|
137
|
+
|
|
138
|
+
## Requirements
|
|
139
|
+
|
|
140
|
+
- Python 3.10+
|
|
141
|
+
- Linux (any flavor) or WSL
|
|
142
|
+
- Terminal with 256-color support
|
|
143
|
+
- AttackLM installed (`pip install attacklm[all]`)
|
|
144
|
+
|
|
145
|
+
No X11, no GPU, no browser required. Works over SSH.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "attacklm-gui"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Terminal GUI wrapper for AttackLM CLI training tools"
|
|
5
|
+
requires-python = ">=3.10"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"textual>=2.0",
|
|
8
|
+
"attacklm",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[project.scripts]
|
|
12
|
+
attacklm-gui = "attacklm_gui.cli:main"
|
|
13
|
+
|
|
14
|
+
[build-system]
|
|
15
|
+
requires = ["setuptools>=75"]
|
|
16
|
+
build-backend = "setuptools.build_meta"
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.packages.find]
|
|
19
|
+
where = ["src"]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Main Textual application for AttackLM GUI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from textual.app import App, ComposeResult
|
|
8
|
+
from textual.binding import Binding
|
|
9
|
+
from textual.widgets import Header, Footer
|
|
10
|
+
|
|
11
|
+
from attacklm_gui.presets import ensure_builtin_presets
|
|
12
|
+
from attacklm_gui.screens.main_menu import MainMenuScreen
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AttackLMApp(App):
|
|
16
|
+
"""Terminal GUI wrapper for AttackLM CLI tools."""
|
|
17
|
+
|
|
18
|
+
TITLE = "AttackLM GUI"
|
|
19
|
+
SUB_TITLE = "v0.1.0"
|
|
20
|
+
CSS_PATH = None # We'll use inline CSS for now
|
|
21
|
+
|
|
22
|
+
BINDINGS = [
|
|
23
|
+
Binding("q", "quit", "Quit", show=True),
|
|
24
|
+
Binding("m", "main_menu", "Main Menu", show=True),
|
|
25
|
+
Binding("?", "help", "Help", show=False),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
def __init__(self) -> None:
|
|
29
|
+
super().__init__()
|
|
30
|
+
self.attacklm_dir = self._find_attacklm_dir()
|
|
31
|
+
|
|
32
|
+
def _find_attacklm_dir(self) -> Path:
|
|
33
|
+
"""Find the AttackLM project directory."""
|
|
34
|
+
# Try common locations
|
|
35
|
+
candidates = [
|
|
36
|
+
Path.cwd(),
|
|
37
|
+
Path.home() / "Projects" / "reverse_engineering" / "AttackLM",
|
|
38
|
+
Path.home() / "AttackLM",
|
|
39
|
+
]
|
|
40
|
+
for c in candidates:
|
|
41
|
+
if (c / "pyproject.toml").exists() and (
|
|
42
|
+
c / "scripts" / "train_template.py"
|
|
43
|
+
).exists():
|
|
44
|
+
return c
|
|
45
|
+
return Path.cwd()
|
|
46
|
+
|
|
47
|
+
def compose(self) -> ComposeResult:
|
|
48
|
+
yield Header()
|
|
49
|
+
yield Footer()
|
|
50
|
+
|
|
51
|
+
def on_mount(self) -> None:
|
|
52
|
+
ensure_builtin_presets()
|
|
53
|
+
self.push_screen(MainMenuScreen())
|
|
54
|
+
|
|
55
|
+
def action_main_menu(self) -> None:
|
|
56
|
+
"""Return to main menu."""
|
|
57
|
+
while len(self.screen_stack) > 1:
|
|
58
|
+
self.pop_screen()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""CLI entry point for attacklm-gui."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main() -> int:
|
|
8
|
+
"""Launch the AttackLM TUI."""
|
|
9
|
+
from attacklm_gui.app import AttackLMApp
|
|
10
|
+
|
|
11
|
+
app = AttackLMApp()
|
|
12
|
+
app.run()
|
|
13
|
+
return 0
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
sys.exit(main())
|