attacklm 0.5.2__tar.gz → 0.5.5__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.
Files changed (208) hide show
  1. {attacklm-0.5.2 → attacklm-0.5.5}/.gitignore +1 -0
  2. {attacklm-0.5.2 → attacklm-0.5.5}/PKG-INFO +18 -20
  3. {attacklm-0.5.2 → attacklm-0.5.5}/README.md +11 -4
  4. {attacklm-0.5.2 → attacklm-0.5.5}/pyproject.toml +28 -2
  5. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/train_all.py +10 -0
  6. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/train_template.py +140 -30
  7. attacklm-0.5.5/src/attacklm/__version__.py +1 -0
  8. attacklm-0.5.2/src/attacklm/__version__.py +0 -1
  9. {attacklm-0.5.2 → attacklm-0.5.5}/.github/workflows/release.yml +0 -0
  10. {attacklm-0.5.2 → attacklm-0.5.5}/ATTRIBUTION.md +0 -0
  11. {attacklm-0.5.2 → attacklm-0.5.5}/CHANGELOG.md +0 -0
  12. {attacklm-0.5.2 → attacklm-0.5.5}/CONTRIBUTING.md +0 -0
  13. {attacklm-0.5.2 → attacklm-0.5.5}/EVALUATION.md +0 -0
  14. {attacklm-0.5.2 → attacklm-0.5.5}/LICENSE +0 -0
  15. {attacklm-0.5.2 → attacklm-0.5.5}/MANIFEST.in +0 -0
  16. {attacklm-0.5.2 → attacklm-0.5.5}/Makefile +0 -0
  17. {attacklm-0.5.2 → attacklm-0.5.5}/NOTICE +0 -0
  18. {attacklm-0.5.2 → attacklm-0.5.5}/QA_BEFORE_RELEASES.md +0 -0
  19. {attacklm-0.5.2 → attacklm-0.5.5}/REPLAY_PLAN.md +0 -0
  20. {attacklm-0.5.2 → attacklm-0.5.5}/data/ATTRIBUTION.md +0 -0
  21. {attacklm-0.5.2 → attacklm-0.5.5}/data/LEGAL.md +0 -0
  22. {attacklm-0.5.2 → attacklm-0.5.5}/data/REMOVAL.md +0 -0
  23. {attacklm-0.5.2 → attacklm-0.5.5}/data/bench/questions.jsonl +0 -0
  24. {attacklm-0.5.2 → attacklm-0.5.5}/data/bench/speed_context.txt +0 -0
  25. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/ATTRIBUTION.md +0 -0
  26. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/GEMINI_RESEARCH_2026-06-11.md +0 -0
  27. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/acquisition_report.json +0 -0
  28. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/manifest.json +0 -0
  29. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/README.md +0 -0
  30. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/_index.json +0 -0
  31. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/LICENSE.md +0 -0
  32. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/SOURCE.md +0 -0
  33. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/base/collection/data.jsonl +0 -0
  34. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/base/discovery/data.jsonl +0 -0
  35. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/base/execution/data.jsonl +0 -0
  36. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/base/exfiltration/data.jsonl +0 -0
  37. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/atomic-red-team/base/persistence/data.jsonl +0 -0
  38. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md +0 -0
  39. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md +0 -0
  40. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/attacklm-synthetic/orchestrator/data.jsonl +0 -0
  41. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/azure-pyrit/LICENSE.md +0 -0
  42. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/azure-pyrit/SOURCE.md +0 -0
  43. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/cyberark-fuzzyai/LICENSE.md +0 -0
  44. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/cyberark-fuzzyai/SOURCE.md +0 -0
  45. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/elastic-rules/LICENSE.md +0 -0
  46. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/elastic-rules/SOURCE.md +0 -0
  47. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/LICENSE.md +0 -0
  48. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/SOURCE.md +0 -0
  49. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/cloud/attacks/data_llm.jsonl +0 -0
  50. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/ics/attacks/data_llm.jsonl +0 -0
  51. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/social_engineering/phishing/data_llm.jsonl +0 -0
  52. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/llm-generated/wireless/attacks/data_llm.jsonl +0 -0
  53. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md +0 -0
  54. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md +0 -0
  55. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/collection/data.jsonl +0 -0
  56. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/credential_access/data.jsonl +0 -0
  57. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/defense_evasion/data.jsonl +0 -0
  58. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/discovery/data.jsonl +0 -0
  59. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/execution/data.jsonl +0 -0
  60. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/lateral_movement/data.jsonl +0 -0
  61. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/persistence/data.jsonl +0 -0
  62. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/base/privilege_escalation/data.jsonl +0 -0
  63. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/metasploit-framework/tools/metasploit/data.jsonl +0 -0
  64. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md +0 -0
  65. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md +0 -0
  66. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-atlas-arsenal/base/discovery/data.jsonl +0 -0
  67. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/LICENSE.md +0 -0
  68. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/SOURCE.md +0 -0
  69. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/base/collection/data.jsonl +0 -0
  70. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/base/discovery/data.jsonl +0 -0
  71. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/base/execution/data.jsonl +0 -0
  72. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/base/exfiltration/data.jsonl +0 -0
  73. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mitre-stockpile/base/persistence/data.jsonl +0 -0
  74. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mordor/LICENSE.md +0 -0
  75. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/mordor/SOURCE.md +0 -0
  76. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/nist-ir/LICENSE.md +0 -0
  77. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/nist-ir/SOURCE.md +0 -0
  78. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/nvidia-garak/LICENSE.md +0 -0
  79. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/nvidia-garak/SOURCE.md +0 -0
  80. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/nvidia-garak/ai/jailbreaking/data.jsonl +0 -0
  81. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptfoo/LICENSE.md +0 -0
  82. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptfoo/SOURCE.md +0 -0
  83. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptfoo/ai/prompt-injection/data.jsonl +0 -0
  84. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptmap/LICENSE.md +0 -0
  85. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptmap/SOURCE.md +0 -0
  86. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/promptmap/ai/prompt-injection/data.jsonl +0 -0
  87. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/LICENSE.md +0 -0
  88. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/SOURCE.md +0 -0
  89. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/base/replay/data_code.jsonl +0 -0
  90. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/base/replay/data_conversation.jsonl +0 -0
  91. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/base/replay/data_factual.jsonl +0 -0
  92. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/replay-general/base/replay/data_reasoning.jsonl +0 -0
  93. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/sigma-hq/LICENSE.md +0 -0
  94. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/sigma-hq/SOURCE.md +0 -0
  95. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/splunk-content/LICENSE.md +0 -0
  96. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/splunk-content/SOURCE.md +0 -0
  97. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md +0 -0
  98. {attacklm-0.5.2 → attacklm-0.5.5}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md +0 -0
  99. {attacklm-0.5.2 → attacklm-0.5.5}/data/golden/prompts.jsonl +0 -0
  100. {attacklm-0.5.2 → attacklm-0.5.5}/data/reference/prompts.jsonl +0 -0
  101. {attacklm-0.5.2 → attacklm-0.5.5}/data/steering/prompts/opsec_aware.txt +0 -0
  102. {attacklm-0.5.2 → attacklm-0.5.5}/data/steering/prompts/opsec_unaware.txt +0 -0
  103. {attacklm-0.5.2 → attacklm-0.5.5}/data/steering/prompts/succinct.txt +0 -0
  104. {attacklm-0.5.2 → attacklm-0.5.5}/data/steering/prompts/verbose.txt +0 -0
  105. {attacklm-0.5.2 → attacklm-0.5.5}/experiments/README.md +0 -0
  106. {attacklm-0.5.2 → attacklm-0.5.5}/experiments/synthetic_dataset_mutator_evol_instruct.py +0 -0
  107. {attacklm-0.5.2 → attacklm-0.5.5}/hf/.gitattributes +0 -0
  108. {attacklm-0.5.2 → attacklm-0.5.5}/hf/README.md +0 -0
  109. {attacklm-0.5.2 → attacklm-0.5.5}/hf/data/manifest.json +0 -0
  110. {attacklm-0.5.2 → attacklm-0.5.5}/hf/dataset_infos.json +0 -0
  111. {attacklm-0.5.2 → attacklm-0.5.5}/hf/scripts/build_hf_dataset.py +0 -0
  112. {attacklm-0.5.2 → attacklm-0.5.5}/hf/scripts/push_to_hf.py +0 -0
  113. {attacklm-0.5.2 → attacklm-0.5.5}/hpo_runs/.gitkeep +0 -0
  114. {attacklm-0.5.2 → attacklm-0.5.5}/hpo_runs/hpo_state.json +0 -0
  115. {attacklm-0.5.2 → attacklm-0.5.5}/hpo_runs/hpo_trial_dataset.jsonl +0 -0
  116. {attacklm-0.5.2 → attacklm-0.5.5}/logs/.gitkeep +0 -0
  117. {attacklm-0.5.2 → attacklm-0.5.5}/notes/BLUE_TEAM_DESIGN_v0.5.0.md +0 -0
  118. {attacklm-0.5.2 → attacklm-0.5.5}/notes/EVAL_DESIGN_v0.4.0.md +0 -0
  119. {attacklm-0.5.2 → attacklm-0.5.5}/notes/STEERING_REVIEW_v0.4.0.md +0 -0
  120. {attacklm-0.5.2 → attacklm-0.5.5}/presets/blue-team.json +0 -0
  121. {attacklm-0.5.2 → attacklm-0.5.5}/presets/purple-team.json +0 -0
  122. {attacklm-0.5.2 → attacklm-0.5.5}/presets/red-team.json +0 -0
  123. {attacklm-0.5.2 → attacklm-0.5.5}/requirements.txt +0 -0
  124. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/_eval_loader.py +0 -0
  125. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_cloud_attack_dataset.py +0 -0
  126. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_ics_dataset.py +0 -0
  127. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_phishing_dataset.py +0 -0
  128. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_red_team_tactics.py +0 -0
  129. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_replay_general.py +0 -0
  130. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_supply_chain_dataset.py +0 -0
  131. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_web_attack_dataset.py +0 -0
  132. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/acquire_wireless_dataset.py +0 -0
  133. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/add_attribution.py +0 -0
  134. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/audit_dataset.py +0 -0
  135. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/augment_attribution.py +0 -0
  136. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/balance_buckets.py +0 -0
  137. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/bucket_loader.py +0 -0
  138. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/build.py +0 -0
  139. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/classify_unrouted_modules.py +0 -0
  140. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/clone_repos.sh +0 -0
  141. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/collect_reference.py +0 -0
  142. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/compare_scores.py +0 -0
  143. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/convert_to_gguf.py +0 -0
  144. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/dedupe_and_import_llm.py +0 -0
  145. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/demo.py +0 -0
  146. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/device_utils.py +0 -0
  147. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/domain_bench.py +0 -0
  148. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/eval_retention.py +0 -0
  149. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_ai_tools_to_jsonl.py +0 -0
  150. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_atomic_red_team_to_jsonl.py +0 -0
  151. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_by_tactic.py +0 -0
  152. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_caldera_plugins_to_jsonl.py +0 -0
  153. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_elastic_rules.py +0 -0
  154. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_infection_monkey_to_jsonl.py +0 -0
  155. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_mordor.py +0 -0
  156. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_nist_ir.py +0 -0
  157. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_rta_to_jsonl.py +0 -0
  158. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_sigma_defensive.py +0 -0
  159. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_splunk_content.py +0 -0
  160. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/extract_threathunter_playbook.py +0 -0
  161. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_dataset.py +0 -0
  162. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_dataset_deterministic.py +0 -0
  163. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_hybrid_dataset.py +0 -0
  164. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_metasploit_dataset.py +0 -0
  165. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_orchestrator.py +0 -0
  166. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_prompt_injection.py +0 -0
  167. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_source_layout.py +0 -0
  168. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/generate_synthetic_scarce.py +0 -0
  169. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/golden_vectors.py +0 -0
  170. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/hpo_runner.py +0 -0
  171. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/import_gguf.sh +0 -0
  172. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/import_to_lmstudio.sh +0 -0
  173. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/infer.py +0 -0
  174. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/init_pipeline.py +0 -0
  175. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/llm_generate_wrapper.py +0 -0
  176. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/merge_adapter.py +0 -0
  177. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/migrate_buckets_to_v021.py +0 -0
  178. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/migrate_v015_to_v020.py +0 -0
  179. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/mitre_tactic_lookup.py +0 -0
  180. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/parse_metasploit_to_jsonl.py +0 -0
  181. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/rebuild_manifest.py +0 -0
  182. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/register_ollama.py +0 -0
  183. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/reorganize_buckets.py +0 -0
  184. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/replay_mixer.py +0 -0
  185. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/run_all_acquisitions.py +0 -0
  186. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/score_candidates.py +0 -0
  187. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/scrub_bpl_callback.py +0 -0
  188. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/setup_buckets.py +0 -0
  189. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/speed_bench.py +0 -0
  190. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/stamp_and_reorg.py +0 -0
  191. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/steering.py +0 -0
  192. {attacklm-0.5.2 → attacklm-0.5.5}/scripts/validate_per_category.py +0 -0
  193. {attacklm-0.5.2 → attacklm-0.5.5}/src/attacklm/__init__.py +0 -0
  194. {attacklm-0.5.2 → attacklm-0.5.5}/src/attacklm/cli.py +0 -0
  195. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_balance_buckets.py +0 -0
  196. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_collect_reference.py +0 -0
  197. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_compare_scores.py +0 -0
  198. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_domain_bench.py +0 -0
  199. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_eval_loader.py +0 -0
  200. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_eval_retention.py +0 -0
  201. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_golden_vectors.py +0 -0
  202. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_init_pipeline.py +0 -0
  203. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_replay_mixer.py +0 -0
  204. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_score_candidates.py +0 -0
  205. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_speed_bench.py +0 -0
  206. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_steering.py +0 -0
  207. {attacklm-0.5.2 → attacklm-0.5.5}/tests/test_thinking_models.py +0 -0
  208. {attacklm-0.5.2 → attacklm-0.5.5}/uv.lock +0 -0
@@ -214,3 +214,4 @@ hf/data/*.parquet
214
214
  #
215
215
  # All archive contents are preserved locally but never pushed to remote.
216
216
  archive/
217
+ unsloth_compiled_cache/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attacklm
3
- Version: 0.5.2
3
+ Version: 0.5.5
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
@@ -25,10 +25,7 @@ Requires-Python: >=3.10
25
25
  Provides-Extra: all
26
26
  Requires-Dist: accelerate==1.13.0; extra == 'all'
27
27
  Requires-Dist: bitsandbytes==0.49.2; extra == 'all'
28
- Requires-Dist: causal-conv1d>=1.4; extra == 'all'
29
28
  Requires-Dist: datasets==5.0.0; extra == 'all'
30
- Requires-Dist: flash-attn>=2.7; extra == 'all'
31
- Requires-Dist: flash-linear-attention>=0.2; extra == 'all'
32
29
  Requires-Dist: gguf; extra == 'all'
33
30
  Requires-Dist: gitpython; extra == 'all'
34
31
  Requires-Dist: huggingface-hub==1.18.0; extra == 'all'
@@ -51,10 +48,7 @@ Requires-Dist: trl==1.5.1; extra == 'all'
51
48
  Provides-Extra: all-cuda
52
49
  Requires-Dist: accelerate==1.13.0; extra == 'all-cuda'
53
50
  Requires-Dist: bitsandbytes==0.49.2; extra == 'all-cuda'
54
- Requires-Dist: causal-conv1d>=1.4; extra == 'all-cuda'
55
51
  Requires-Dist: datasets==5.0.0; extra == 'all-cuda'
56
- Requires-Dist: flash-attn>=2.7; extra == 'all-cuda'
57
- Requires-Dist: flash-linear-attention>=0.2; extra == 'all-cuda'
58
52
  Requires-Dist: gguf; extra == 'all-cuda'
59
53
  Requires-Dist: gitpython; extra == 'all-cuda'
60
54
  Requires-Dist: huggingface-hub==1.18.0; extra == 'all-cuda'
@@ -95,9 +89,6 @@ Requires-Dist: bitsandbytes==0.49.2; extra == 'cuda'
95
89
  Requires-Dist: torch==2.12.0; extra == 'cuda'
96
90
  Requires-Dist: torchvision==0.27.0; extra == 'cuda'
97
91
  Provides-Extra: cuda-extras
98
- Requires-Dist: causal-conv1d>=1.4; extra == 'cuda-extras'
99
- Requires-Dist: flash-attn>=2.7; extra == 'cuda-extras'
100
- Requires-Dist: flash-linear-attention>=0.2; extra == 'cuda-extras'
101
92
  Provides-Extra: dev
102
93
  Requires-Dist: ipython; extra == 'dev'
103
94
  Requires-Dist: mypy; extra == 'dev'
@@ -110,6 +101,10 @@ Provides-Extra: extract
110
101
  Requires-Dist: gitpython; extra == 'extract'
111
102
  Requires-Dist: pyyaml; extra == 'extract'
112
103
  Requires-Dist: requests; extra == 'extract'
104
+ Provides-Extra: flash-attn
105
+ Requires-Dist: causal-conv1d>=1.4; extra == 'flash-attn'
106
+ Requires-Dist: flash-attn>=2.7; extra == 'flash-attn'
107
+ Requires-Dist: flash-linear-attention>=0.2; extra == 'flash-attn'
113
108
  Provides-Extra: infer
114
109
  Requires-Dist: bitsandbytes==0.49.2; extra == 'infer'
115
110
  Requires-Dist: huggingface-hub==1.18.0; extra == 'infer'
@@ -151,10 +146,7 @@ Provides-Extra: rocm-extras
151
146
  Provides-Extra: train
152
147
  Requires-Dist: accelerate==1.13.0; extra == 'train'
153
148
  Requires-Dist: bitsandbytes==0.49.2; extra == 'train'
154
- Requires-Dist: causal-conv1d>=1.4; extra == 'train'
155
149
  Requires-Dist: datasets==5.0.0; extra == 'train'
156
- Requires-Dist: flash-attn>=2.7; extra == 'train'
157
- Requires-Dist: flash-linear-attention>=0.2; extra == 'train'
158
150
  Requires-Dist: huggingface-hub==1.18.0; extra == 'train'
159
151
  Requires-Dist: kernels<0.13,>=0.12; extra == 'train'
160
152
  Requires-Dist: peft==0.19.1; extra == 'train'
@@ -177,10 +169,7 @@ Requires-Dist: trl==1.5.1; extra == 'train-base'
177
169
  Provides-Extra: train-cuda
178
170
  Requires-Dist: accelerate==1.13.0; extra == 'train-cuda'
179
171
  Requires-Dist: bitsandbytes==0.49.2; extra == 'train-cuda'
180
- Requires-Dist: causal-conv1d>=1.4; extra == 'train-cuda'
181
172
  Requires-Dist: datasets==5.0.0; extra == 'train-cuda'
182
- Requires-Dist: flash-attn>=2.7; extra == 'train-cuda'
183
- Requires-Dist: flash-linear-attention>=0.2; extra == 'train-cuda'
184
173
  Requires-Dist: huggingface-hub==1.18.0; extra == 'train-cuda'
185
174
  Requires-Dist: kernels<0.13,>=0.12; extra == 'train-cuda'
186
175
  Requires-Dist: peft==0.19.1; extra == 'train-cuda'
@@ -203,6 +192,8 @@ Requires-Dist: torch==2.12.0; extra == 'train-rocm'
203
192
  Requires-Dist: torchvision==0.27.0; extra == 'train-rocm'
204
193
  Requires-Dist: transformers==5.10.2; extra == 'train-rocm'
205
194
  Requires-Dist: trl==1.5.1; extra == 'train-rocm'
195
+ Provides-Extra: unsloth
196
+ Requires-Dist: unsloth>=2026.6; extra == 'unsloth'
206
197
  Description-Content-Type: text/markdown
207
198
 
208
199
  # AttackLM
@@ -279,17 +270,20 @@ The full per-source map:
279
270
  # 1. Install uv (Python package manager, ~10MB)
280
271
  curl -LsSf https://astral.sh/uv/install.sh | sh
281
272
 
282
- # 2. Install AttackLM from PyPI with the full CUDA training stack
273
+ # 2. Install PyTorch + Triton first (required by flash-attn and Unsloth)
274
+ uv pip install torch==2.12.0 torchvision==0.27.0 triton
275
+
276
+ # 3. Install AttackLM from PyPI with the full CUDA training stack
283
277
  uv pip install "attacklm[all]"
284
278
 
285
- # 3. Clone the repo for the training data (the PyPI package is code-only)
279
+ # 4. Clone the repo for the training data (the PyPI package is code-only)
286
280
  git clone https://github.com/Veedubin/AttackLM.git
287
281
  cd AttackLM
288
282
 
289
- # 4. Initialize the dataset (probes local `data/` first; falls back to git clone)
283
+ # 5. Initialize the dataset (probes local `data/` first; falls back to git clone)
290
284
  attacklm-init --yes
291
285
 
292
- # 5. Train
286
+ # 6. Train
293
287
  attacklm-train-all --single-model \
294
288
  --dataset base/ \
295
289
  --base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
@@ -339,6 +333,10 @@ build anything by hand.
339
333
 
340
334
  **Install from PyPI (recommended):**
341
335
  ```bash
336
+ # PyTorch + Triton must be installed first (flash-attn and Unsloth need them)
337
+ uv pip install torch==2.12.0 torchvision==0.27.0 triton
338
+
339
+ # Then install AttackLM
342
340
  uv pip install "attacklm[all]" # CUDA training stack
343
341
  uv pip install "attacklm[all-rocm]" # ROCm training stack
344
342
  uv pip install "attacklm[infer]" # CPU / Apple Silicon (inference only)
@@ -72,17 +72,20 @@ The full per-source map:
72
72
  # 1. Install uv (Python package manager, ~10MB)
73
73
  curl -LsSf https://astral.sh/uv/install.sh | sh
74
74
 
75
- # 2. Install AttackLM from PyPI with the full CUDA training stack
75
+ # 2. Install PyTorch + Triton first (required by flash-attn and Unsloth)
76
+ uv pip install torch==2.12.0 torchvision==0.27.0 triton
77
+
78
+ # 3. Install AttackLM from PyPI with the full CUDA training stack
76
79
  uv pip install "attacklm[all]"
77
80
 
78
- # 3. Clone the repo for the training data (the PyPI package is code-only)
81
+ # 4. Clone the repo for the training data (the PyPI package is code-only)
79
82
  git clone https://github.com/Veedubin/AttackLM.git
80
83
  cd AttackLM
81
84
 
82
- # 4. Initialize the dataset (probes local `data/` first; falls back to git clone)
85
+ # 5. Initialize the dataset (probes local `data/` first; falls back to git clone)
83
86
  attacklm-init --yes
84
87
 
85
- # 5. Train
88
+ # 6. Train
86
89
  attacklm-train-all --single-model \
87
90
  --dataset base/ \
88
91
  --base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
@@ -132,6 +135,10 @@ build anything by hand.
132
135
 
133
136
  **Install from PyPI (recommended):**
134
137
  ```bash
138
+ # PyTorch + Triton must be installed first (flash-attn and Unsloth need them)
139
+ uv pip install torch==2.12.0 torchvision==0.27.0 triton
140
+
141
+ # Then install AttackLM
135
142
  uv pip install "attacklm[all]" # CUDA training stack
136
143
  uv pip install "attacklm[all-rocm]" # ROCm training stack
137
144
  uv pip install "attacklm[infer]" # CPU / Apple Silicon (inference only)
@@ -150,7 +150,14 @@ rocm = [
150
150
  # `causal_conv1d` and `flash_linear_attention` are CUDA C++ extensions.
151
151
  # ROCm users can SKIP these — the Qwen3NextForCausalLM modeling has pure-PyTorch
152
152
  # fallbacks (slower but works).
153
- cuda-extras = [
153
+ #
154
+ # IMPORTANT: flash-attn and causal-conv1d need torch at build time but don't
155
+ # declare it in their build-system.requires. They are NOT included in [all]
156
+ # or [train-cuda] — install them separately AFTER torch is in the environment:
157
+ # uv pip install attacklm[all]
158
+ # uv pip install attacklm[flash-attn]
159
+ cuda-extras = []
160
+ flash-attn = [
154
161
  "flash-attn>=2.7", # requires CUDA dev tools to build
155
162
  "causal-conv1d>=1.4", # CUDA-only
156
163
  "flash-linear-attention>=0.2", # CUDA-only
@@ -179,6 +186,16 @@ convert = [
179
186
  "gguf",
180
187
  "llama-cpp-python",
181
188
  ]
189
+ # Unsloth: 2-5x faster training, 70% less VRAM.
190
+ # NOTE: Unsloth requires trl<=0.24.0 which conflicts with our trl==1.5.1.
191
+ # Install Unsloth in a separate venv or let pip resolve the conflict:
192
+ # pip install unsloth # will downgrade trl automatically
193
+ # Then use: attacklm-train-all --use-unsloth ...
194
+ # The [unsloth] extra is provided for convenience but is NOT included
195
+ # in [all] due to the trl version conflict.
196
+ unsloth = [
197
+ "unsloth>=2026.6",
198
+ ]
182
199
  dev = [
183
200
  "pytest",
184
201
  "ruff",
@@ -234,4 +251,13 @@ packages = ["src/attacklm"]
234
251
  [tool.hatch.build.targets.wheel.force-include]
235
252
 
236
253
  [tool.hatch.version]
237
- path = "src/attacklm/__version__.py"
254
+ path = "src/attacklm/__version__.py"
255
+
256
+ # ── Build-time dependencies for packages that don't declare them ────────────────
257
+ # flash-attn and causal-conv1d need torch at build time but don't list it in
258
+ # their build-system.requires. Without this, `uv pip install attacklm[all]` fails
259
+ # with "ModuleNotFoundError: No module named 'torch'" during the flash-attn build.
260
+ # This tells uv to pre-install torch before building these packages.
261
+ [tool.uv.extra-build-dependencies]
262
+ flash-attn = ["torch"]
263
+ causal-conv1d = ["torch"]
@@ -418,6 +418,8 @@ def build_train_cmd(
418
418
  cmd.extend(["--target-modules", args.target_modules])
419
419
  if getattr(args, "moe_safe_target", False):
420
420
  cmd.append("--moe-safe-target")
421
+ if getattr(args, "use_unsloth", False):
422
+ cmd.append("--use-unsloth")
421
423
  # v0.1.6+: pass dataset specs so train_template can record them in
422
424
  # state.json[dataset.specs] (reproducibility).
423
425
  if dataset_specs:
@@ -736,6 +738,14 @@ def main():
736
738
  help="Restrict LoRA to attention + MLP, force bf16, disable 4-bit quantization "
737
739
  "for MoE models in train_template.py (default: OFF).",
738
740
  )
741
+ parser.add_argument(
742
+ "--use-unsloth",
743
+ action="store_true",
744
+ default=False,
745
+ help="Use Unsloth's optimized model loading and LoRA kernels "
746
+ "(2-5x faster, 70% less VRAM). Requires 'pip install unsloth'. "
747
+ "Passed through to train_template.py (default: OFF).",
748
+ )
739
749
  # ---- Experience replay flags ----
740
750
  parser.add_argument(
741
751
  "--replay-source",
@@ -355,6 +355,20 @@ Examples:
355
355
  "per Unsloth guidance. Default: OFF."
356
356
  ),
357
357
  )
358
+ parser.add_argument(
359
+ "--use-unsloth",
360
+ action="store_true",
361
+ default=False,
362
+ help=(
363
+ "Use Unsloth's optimized model loading and LoRA kernels. "
364
+ "Unsloth provides 2-5x faster training, 70% less VRAM, and "
365
+ "8x longer context support vs standard HF QLoRA. Requires "
366
+ "'uv pip install attacklm[unsloth]' or 'pip install unsloth'. "
367
+ "When enabled, Unsloth's FastLanguageModel replaces the "
368
+ "standard AutoModelForCausalLM + BitsAndBytes pipeline. "
369
+ "Default: OFF (standard HF QLoRA)."
370
+ ),
371
+ )
358
372
 
359
373
  return parser.parse_args()
360
374
 
@@ -1431,12 +1445,17 @@ def main() -> None:
1431
1445
  if args.moe_safe_target
1432
1446
  else "OFF"
1433
1447
  )
1448
+ _unsloth_display = (
1449
+ "ON (FastLanguageModel + optimized LoRA kernels)" if args.use_unsloth else "OFF"
1450
+ )
1434
1451
 
1435
1452
  print("=" * 60)
1436
1453
  print(" TRAINING PLAN")
1437
1454
  print("=" * 60)
1438
1455
  print(f" Model: {args.base_model}")
1439
- if not args.moe_safe_target:
1456
+ if args.use_unsloth:
1457
+ print(" Quantization: 4-bit (Unsloth internal)")
1458
+ elif not args.moe_safe_target:
1440
1459
  print(" Quantization: 4-bit NF4 (double quant)")
1441
1460
  else:
1442
1461
  print(" Quantization: NONE (bf16 full-precision for MoE)")
@@ -1448,6 +1467,7 @@ def main() -> None:
1448
1467
  print(f" DoRA: {_dora_display}")
1449
1468
  print(f" LoftQ init: {_loftq_display}")
1450
1469
  print(f" MoE-safe target: {_moe_display}")
1470
+ print(f" Unsloth: {_unsloth_display}")
1451
1471
  print(f" Epochs: {args.epochs}")
1452
1472
  print(f" Batch size: {args.batch_size}")
1453
1473
  print(f" Max seq length: {args.max_length}")
@@ -1482,6 +1502,12 @@ def main() -> None:
1482
1502
  print(" Memory estimate for Qwen2.5-7B QLoRA:")
1483
1503
  print(" ~10-12 GB VRAM at batch_size=2, max_length=2048")
1484
1504
  print(" ~6-8 GB VRAM at batch_size=1, max_length=1024")
1505
+ if args.use_unsloth:
1506
+ print("")
1507
+ print(" With --use-unsloth (70% less VRAM):")
1508
+ print(" ~4-5 GB VRAM at batch_size=2, max_length=2048")
1509
+ print(" ~3-4 GB VRAM at batch_size=1, max_length=1024")
1510
+ print(" ~13B model fits in 16GB with Unsloth QLoRA")
1485
1511
  print("=" * 60)
1486
1512
  return
1487
1513
 
@@ -1585,6 +1611,22 @@ def main() -> None:
1585
1611
  )
1586
1612
  sys.exit(1)
1587
1613
 
1614
+ # --- Unsloth: import and verify availability ---
1615
+ _unsloth_available = False
1616
+ if args.use_unsloth:
1617
+ try:
1618
+ from unsloth import FastLanguageModel, is_bfloat16_supported
1619
+
1620
+ _unsloth_available = True
1621
+ print(" Unsloth: loaded (FastLanguageModel available)")
1622
+ except ImportError:
1623
+ print(
1624
+ "ERROR: --use-unsloth requires the 'unsloth' package.\n"
1625
+ " Install: uv pip install attacklm[unsloth]\n"
1626
+ " Or: pip install unsloth"
1627
+ )
1628
+ sys.exit(1)
1629
+
1588
1630
  # --- Build quantization config ---
1589
1631
  import torch
1590
1632
 
@@ -1617,18 +1659,25 @@ def main() -> None:
1617
1659
  # BitsAndBytes 4-bit does not support MoE expert weights per Unsloth
1618
1660
  # guidance. For MoE models, we load in bf16 and only apply LoRA to the
1619
1661
  # attention + MLP modules (excluding router/gate/lm_head).
1620
- skip_quantization = args.moe_safe_target
1662
+ # --use-unsloth: Unsloth handles quantization internally via its own
1663
+ # load_in_4bit parameter. We skip BitsAndBytes entirely.
1664
+ skip_quantization = args.moe_safe_target or args.use_unsloth
1621
1665
 
1622
1666
  if skip_quantization:
1623
- bnb_config = None # No quantization for MoE-safe mode
1624
- # Force bf16 for MoE models
1625
- if compute_type != "bf16":
1626
- print(
1627
- " --moe-safe-target: overriding compute dtype to bf16 "
1628
- "(required for MoE models without 4-bit quantization)"
1629
- )
1630
- compute_type = "bf16"
1631
- compute_dtype = torch.bfloat16
1667
+ bnb_config = None # No quantization for MoE-safe or Unsloth mode
1668
+ if args.moe_safe_target:
1669
+ # Force bf16 for MoE models
1670
+ if compute_type != "bf16":
1671
+ print(
1672
+ " --moe-safe-target: overriding compute dtype to bf16 "
1673
+ "(required for MoE models without 4-bit quantization)"
1674
+ )
1675
+ compute_type = "bf16"
1676
+ compute_dtype = torch.bfloat16
1677
+ elif args.use_unsloth:
1678
+ # Unsloth handles dtype internally; we still set compute_dtype
1679
+ # for the SFTConfig mixed-precision flags
1680
+ compute_dtype = torch.bfloat16 if compute_type == "bf16" else torch.float16
1632
1681
  else:
1633
1682
  bnb_config = get_quantization_config()
1634
1683
 
@@ -1658,6 +1707,8 @@ def main() -> None:
1658
1707
 
1659
1708
  print(f"Loading model: {args.base_model}")
1660
1709
  print(f" Detected quantization: {quant_label}")
1710
+ if args.use_unsloth:
1711
+ print(" Unsloth: enabled (FastLanguageModel + optimized LoRA kernels)")
1661
1712
 
1662
1713
  # LoftQ init: if the model is already quantized, LoftQ cannot apply.
1663
1714
  # Print a warning and fall back to default init.
@@ -1728,9 +1779,36 @@ def main() -> None:
1728
1779
  pass
1729
1780
 
1730
1781
  try:
1731
- model = AutoModelForCausalLM.from_pretrained(
1732
- base_model_resolved, **load_kwargs
1733
- )
1782
+ if args.use_unsloth and _unsloth_available:
1783
+ # --- Unsloth model loading path ---
1784
+ # Unsloth's FastLanguageModel handles 4-bit quantization
1785
+ # internally (no BitsAndBytesConfig needed). It also
1786
+ # provides optimized LoRA kernels that are 2-5x faster
1787
+ # and use 70% less VRAM than standard HF QLoRA.
1788
+ print(" Loading with Unsloth FastLanguageModel...")
1789
+ model, tokenizer = FastLanguageModel.from_pretrained(
1790
+ model_name=base_model_resolved,
1791
+ max_seq_length=args.max_length,
1792
+ load_in_4bit=True,
1793
+ dtype=None, # Auto-detect from GPU
1794
+ trust_remote_code=True,
1795
+ )
1796
+ # Unsloth returns (model, tokenizer) — use its tokenizer
1797
+ # which has the correct chat template and special tokens
1798
+ model, tokenizer = FastLanguageModel.from_pretrained(
1799
+ model_name=base_model_resolved,
1800
+ max_seq_length=args.max_length,
1801
+ load_in_4bit=True,
1802
+ dtype=None, # Auto-detect from GPU
1803
+ trust_remote_code=True,
1804
+ )
1805
+ if tokenizer.pad_token is None:
1806
+ tokenizer.pad_token = tokenizer.eos_token
1807
+ print(" Unsloth: model loaded with internal 4-bit quantization")
1808
+ else:
1809
+ model = AutoModelForCausalLM.from_pretrained(
1810
+ base_model_resolved, **load_kwargs
1811
+ )
1734
1812
  except (ImportError, ValueError, ModuleNotFoundError) as e:
1735
1813
  error_str = str(e).lower()
1736
1814
  if "flash" in error_str or "flash_attention" in error_str:
@@ -1901,24 +1979,56 @@ def main() -> None:
1901
1979
  # (before training plan display) so they can appear in the plan output.
1902
1980
  # The LoftQ warning for pre-quantized models was also printed earlier.
1903
1981
 
1904
- lora_config = get_qlora_config(
1905
- lora_r=args.lora_r,
1906
- lora_alpha=args.lora_alpha,
1907
- lora_dropout=args.lora_dropout,
1908
- use_rslora=args.use_rslora,
1909
- target_modules=target_modules_list,
1910
- use_dora=args.use_dora,
1911
- init_lora_weights=init_lora_weights,
1912
- )
1913
-
1914
- if args.use_dora:
1915
- print(" DoRA/QDoRA enabled (use_dora=True)")
1916
- if args.use_rslora:
1917
- print(" RSLoRA enabled (use_rslora=True)")
1982
+ if args.use_unsloth and _unsloth_available:
1983
+ # Unsloth LoRA path: FastLanguageModel.get_peft_model uses
1984
+ # optimized Triton kernels for 2-5x faster training and
1985
+ # 70% less VRAM than standard HF PEFT.
1986
+ print(" Unsloth: applying optimized LoRA via FastLanguageModel.get_peft_model")
1987
+ model = FastLanguageModel.get_peft_model(
1988
+ model,
1989
+ r=args.lora_r,
1990
+ lora_alpha=args.lora_alpha,
1991
+ lora_dropout=args.lora_dropout,
1992
+ target_modules=target_modules_list
1993
+ or [
1994
+ "q_proj",
1995
+ "k_proj",
1996
+ "v_proj",
1997
+ "o_proj",
1998
+ "gate_proj",
1999
+ "up_proj",
2000
+ "down_proj",
2001
+ ],
2002
+ use_gradient_checkpointing="unsloth", # Unsloth's optimized checkpointing
2003
+ random_state=42,
2004
+ use_rslora=args.use_rslora,
2005
+ loftq_config=None, # Unsloth handles quantization internally
2006
+ )
2007
+ if args.use_dora:
2008
+ print(
2009
+ " WARNING: DoRA not supported by Unsloth's get_peft_model. "
2010
+ "Falling back to standard LoRA. Use --no-use-unsloth for DoRA."
2011
+ )
1918
2012
  else:
1919
- print(" RSLoRA disabled (classic LoRA scaling alpha/r)")
2013
+ lora_config = get_qlora_config(
2014
+ lora_r=args.lora_r,
2015
+ lora_alpha=args.lora_alpha,
2016
+ lora_dropout=args.lora_dropout,
2017
+ use_rslora=args.use_rslora,
2018
+ target_modules=target_modules_list,
2019
+ use_dora=args.use_dora,
2020
+ init_lora_weights=init_lora_weights,
2021
+ )
2022
+
2023
+ if args.use_dora:
2024
+ print(" DoRA/QDoRA enabled (use_dora=True)")
2025
+ if args.use_rslora:
2026
+ print(" RSLoRA enabled (use_rslora=True)")
2027
+ else:
2028
+ print(" RSLoRA disabled (classic LoRA scaling alpha/r)")
2029
+
2030
+ model = get_peft_model(model, lora_config)
1920
2031
 
1921
- model = get_peft_model(model, lora_config)
1922
2032
  model.print_trainable_parameters()
1923
2033
 
1924
2034
  # --- Formatting function for chat template ---
@@ -0,0 +1 @@
1
+ __version__ = "0.5.5"
@@ -1 +0,0 @@
1
- __version__ = "0.5.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes