openweights 0.1.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.
Files changed (203) hide show
  1. openweights-0.1.0/.dockerignore +8 -0
  2. openweights-0.1.0/.env.example +3 -0
  3. openweights-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  4. openweights-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +12 -0
  5. openweights-0.1.0/.github/workflows/ci.yaml +99 -0
  6. openweights-0.1.0/.github/workflows/manual_publish.yaml +24 -0
  7. openweights-0.1.0/.gitignore +76 -0
  8. openweights-0.1.0/.pdm-python +1 -0
  9. openweights-0.1.0/LICENSE.txt +21 -0
  10. openweights-0.1.0/PKG-INFO +139 -0
  11. openweights-0.1.0/README.md +113 -0
  12. openweights-0.1.0/docs/finetuning.md +144 -0
  13. openweights-0.1.0/entrypoint.sh +60 -0
  14. openweights-0.1.0/example/analyze_hparam_sweep.ipynb +923 -0
  15. openweights-0.1.0/example/cancel.py +12 -0
  16. openweights-0.1.0/example/compute_outputs.py +18 -0
  17. openweights-0.1.0/example/custom_job/README.md +36 -0
  18. openweights-0.1.0/example/custom_job/add_numbers.py +17 -0
  19. openweights-0.1.0/example/custom_job/start_custom_job.py +64 -0
  20. openweights-0.1.0/example/download.py +65 -0
  21. openweights-0.1.0/example/gradio_ui_with_temporary_api.py +35 -0
  22. openweights-0.1.0/example/guided-inference/guided_inference.py +138 -0
  23. openweights-0.1.0/example/guided-inference/messages.jsonl +1 -0
  24. openweights-0.1.0/example/guided-inference/start_custom_job.py +103 -0
  25. openweights-0.1.0/example/hparams_sweep.py +92 -0
  26. openweights-0.1.0/example/multi_lora_deploy.py +12 -0
  27. openweights-0.1.0/example/multi_model_chat.py +82 -0
  28. openweights-0.1.0/example/restart_failed.py +13 -0
  29. openweights-0.1.0/example/run_ft_job.py +43 -0
  30. openweights-0.1.0/example/run_inference_job.py +51 -0
  31. openweights-0.1.0/example/run_script_job.py +34 -0
  32. openweights-0.1.0/openweights/__init__.py +3 -0
  33. openweights-0.1.0/openweights/client/__init__.py +176 -0
  34. openweights-0.1.0/openweights/client/cache_on_disk.py +34 -0
  35. openweights-0.1.0/openweights/client/chat.py +135 -0
  36. openweights-0.1.0/openweights/client/custom_job.py +96 -0
  37. openweights-0.1.0/openweights/client/events.py +42 -0
  38. openweights-0.1.0/openweights/client/files.py +106 -0
  39. openweights-0.1.0/openweights/client/jobs.py +293 -0
  40. openweights-0.1.0/openweights/client/run.py +189 -0
  41. openweights-0.1.0/openweights/client/temporary_api.py +231 -0
  42. openweights-0.1.0/openweights/cluster/.gitignore +1 -0
  43. openweights-0.1.0/openweights/cluster/README.md +32 -0
  44. openweights-0.1.0/openweights/cluster/org_manager.py +366 -0
  45. openweights-0.1.0/openweights/cluster/start_runpod.py +211 -0
  46. openweights-0.1.0/openweights/cluster/supervisor.py +177 -0
  47. openweights-0.1.0/openweights/dashboard/README.md +77 -0
  48. openweights-0.1.0/openweights/dashboard/backend/database.py +432 -0
  49. openweights-0.1.0/openweights/dashboard/backend/main.py +285 -0
  50. openweights-0.1.0/openweights/dashboard/backend/models.py +69 -0
  51. openweights-0.1.0/openweights/dashboard/backend/static/assets/ow.svg +22 -0
  52. openweights-0.1.0/openweights/dashboard/backend/static/assets/vite.svg +1 -0
  53. openweights-0.1.0/openweights/dashboard/backend/utils.py +143 -0
  54. openweights-0.1.0/openweights/dashboard/deploy.sh +41 -0
  55. openweights-0.1.0/openweights/dashboard/frontend/.gitignore +24 -0
  56. openweights-0.1.0/openweights/dashboard/frontend/README.md +50 -0
  57. openweights-0.1.0/openweights/dashboard/frontend/eslint.config.js +28 -0
  58. openweights-0.1.0/openweights/dashboard/frontend/index.html +13 -0
  59. openweights-0.1.0/openweights/dashboard/frontend/package-lock.json +7839 -0
  60. openweights-0.1.0/openweights/dashboard/frontend/package.json +40 -0
  61. openweights-0.1.0/openweights/dashboard/frontend/public/ow.svg +22 -0
  62. openweights-0.1.0/openweights/dashboard/frontend/public/vite.svg +1 -0
  63. openweights-0.1.0/openweights/dashboard/frontend/src/App.css +47 -0
  64. openweights-0.1.0/openweights/dashboard/frontend/src/App.tsx +300 -0
  65. openweights-0.1.0/openweights/dashboard/frontend/src/api.ts +292 -0
  66. openweights-0.1.0/openweights/dashboard/frontend/src/assets/react.svg +1 -0
  67. openweights-0.1.0/openweights/dashboard/frontend/src/components/Auth/Auth.tsx +231 -0
  68. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/FileContent.tsx +40 -0
  69. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/JobDetailView.tsx +213 -0
  70. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/MetricsDisplay.tsx +90 -0
  71. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/MetricsPlots.tsx +179 -0
  72. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/OutputsDisplay.tsx +62 -0
  73. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/RunDetailView.tsx +147 -0
  74. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/WorkerDetailView.tsx +257 -0
  75. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews/index.ts +3 -0
  76. openweights-0.1.0/openweights/dashboard/frontend/src/components/DetailViews.tsx +1 -0
  77. openweights-0.1.0/openweights/dashboard/frontend/src/components/JobsListView.tsx +134 -0
  78. openweights-0.1.0/openweights/dashboard/frontend/src/components/JobsView.tsx +366 -0
  79. openweights-0.1.0/openweights/dashboard/frontend/src/components/Organizations/OrganizationDetail.tsx +592 -0
  80. openweights-0.1.0/openweights/dashboard/frontend/src/components/Organizations/OrganizationList.tsx +227 -0
  81. openweights-0.1.0/openweights/dashboard/frontend/src/components/Organizations/OrganizationSwitcher.tsx +39 -0
  82. openweights-0.1.0/openweights/dashboard/frontend/src/components/Organizations/OrganizationsList.tsx +168 -0
  83. openweights-0.1.0/openweights/dashboard/frontend/src/components/Organizations/TokensTab.tsx +261 -0
  84. openweights-0.1.0/openweights/dashboard/frontend/src/components/RefreshButton.tsx +33 -0
  85. openweights-0.1.0/openweights/dashboard/frontend/src/components/RunsListView.tsx +134 -0
  86. openweights-0.1.0/openweights/dashboard/frontend/src/components/RunsView.tsx +332 -0
  87. openweights-0.1.0/openweights/dashboard/frontend/src/components/StatusCheckboxes.tsx +62 -0
  88. openweights-0.1.0/openweights/dashboard/frontend/src/components/TokenView.tsx +245 -0
  89. openweights-0.1.0/openweights/dashboard/frontend/src/components/ViewToggle.tsx +33 -0
  90. openweights-0.1.0/openweights/dashboard/frontend/src/components/WorkersListView.tsx +140 -0
  91. openweights-0.1.0/openweights/dashboard/frontend/src/components/WorkersView.tsx +357 -0
  92. openweights-0.1.0/openweights/dashboard/frontend/src/contexts/AuthContext.tsx +103 -0
  93. openweights-0.1.0/openweights/dashboard/frontend/src/contexts/OrganizationContext.tsx +92 -0
  94. openweights-0.1.0/openweights/dashboard/frontend/src/index.css +59 -0
  95. openweights-0.1.0/openweights/dashboard/frontend/src/main.tsx +10 -0
  96. openweights-0.1.0/openweights/dashboard/frontend/src/supabaseClient.ts +11 -0
  97. openweights-0.1.0/openweights/dashboard/frontend/src/types/supabase.ts +63 -0
  98. openweights-0.1.0/openweights/dashboard/frontend/src/types.ts +64 -0
  99. openweights-0.1.0/openweights/dashboard/frontend/src/vite-env.d.ts +1 -0
  100. openweights-0.1.0/openweights/dashboard/frontend/tsconfig.app.json +26 -0
  101. openweights-0.1.0/openweights/dashboard/frontend/tsconfig.json +7 -0
  102. openweights-0.1.0/openweights/dashboard/frontend/tsconfig.node.json +24 -0
  103. openweights-0.1.0/openweights/dashboard/frontend/vite.config.ts +8 -0
  104. openweights-0.1.0/openweights/dashboard/runpod-startup.sh +107 -0
  105. openweights-0.1.0/openweights/dashboard/screenshots/job_details.png +0 -0
  106. openweights-0.1.0/openweights/dashboard/screenshots/jobs_view.png +0 -0
  107. openweights-0.1.0/openweights/dashboard/screenshots/run_details.png +0 -0
  108. openweights-0.1.0/openweights/dashboard/screenshots/workers.png +0 -0
  109. openweights-0.1.0/openweights/utils.py +250 -0
  110. openweights-0.1.0/openweights/validate.py +276 -0
  111. openweights-0.1.0/openweights/worker/__init__.py +0 -0
  112. openweights-0.1.0/openweights/worker/dpo_ft.py +67 -0
  113. openweights-0.1.0/openweights/worker/gpu_health_check.py +111 -0
  114. openweights-0.1.0/openweights/worker/inference.py +140 -0
  115. openweights-0.1.0/openweights/worker/main.py +435 -0
  116. openweights-0.1.0/openweights/worker/orpo_ft.py +64 -0
  117. openweights-0.1.0/openweights/worker/sft.py +109 -0
  118. openweights-0.1.0/openweights/worker/training.py +94 -0
  119. openweights-0.1.0/openweights/worker/utils.py +88 -0
  120. openweights-0.1.0/ow-axolotl.Dockerfile +37 -0
  121. openweights-0.1.0/ow-inference.Dockerfile +30 -0
  122. openweights-0.1.0/ow-unsloth.Dockerfile +24 -0
  123. openweights-0.1.0/pyproject.toml +35 -0
  124. openweights-0.1.0/scripts/migrate_files.py +106 -0
  125. openweights-0.1.0/scripts/use_local_vllm_client.py +37 -0
  126. openweights-0.1.0/supabase/.gitignore +4 -0
  127. openweights-0.1.0/supabase/config.toml +256 -0
  128. openweights-0.1.0/supabase/migrations/20241120094415_remote_schema.sql +161 -0
  129. openweights-0.1.0/supabase/migrations/20241120161019_add_gpu_columns.sql +9 -0
  130. openweights-0.1.0/supabase/migrations/20241127132826_add_docker_image.sql +8 -0
  131. openweights-0.1.0/supabase/migrations/20241127153031_add_docker_image_to_workers.sql +1 -0
  132. openweights-0.1.0/supabase/migrations/20241202233213_add_updated_at_columns.sql +52 -0
  133. openweights-0.1.0/supabase/migrations/20241203000542_add_api_job_type.sql +2 -0
  134. openweights-0.1.0/supabase/migrations/20241205000000_add_organizations.sql +67 -0
  135. openweights-0.1.0/supabase/migrations/20241205000001_add_organization_functions.sql +124 -0
  136. openweights-0.1.0/supabase/migrations/20241205000002_add_rls_policies.sql +66 -0
  137. openweights-0.1.0/supabase/migrations/20241205000003_add_service_accounts.sql +151 -0
  138. openweights-0.1.0/supabase/migrations/20241205000004_add_storage_policies.sql +130 -0
  139. openweights-0.1.0/supabase/migrations/20241205000005_add_token_functions.sql +46 -0
  140. openweights-0.1.0/supabase/migrations/20241205000006_fix_jwt_secret.sql +22 -0
  141. openweights-0.1.0/supabase/migrations/20241205000007_add_organization_secrets.sql +184 -0
  142. openweights-0.1.0/supabase/migrations/20241205000008_fix_member_functions.sql +83 -0
  143. openweights-0.1.0/supabase/migrations/20241205000009_fix_email_ambiguity.sql +83 -0
  144. openweights-0.1.0/supabase/migrations/20241205000010_remove_token_org_fallback.sql +25 -0
  145. openweights-0.1.0/supabase/migrations/20241205000011_add_job_timeout.sql +20 -0
  146. openweights-0.1.0/supabase/migrations/20250101195830_add_worker_logfile.sql +8 -0
  147. openweights-0.1.0/supabase/migrations/20250101195831_add_custom_job_type.sql +2 -0
  148. openweights-0.1.0/supabase/migrations/20250115171900_add_job_locking_functions.sql +38 -0
  149. openweights-0.1.0/supabase/migrations/20250116110200_fix_job_locking_naming.sql +50 -0
  150. openweights-0.1.0/supabase/migrations/20250116111600_fix_job_id_dtypes.sql +51 -0
  151. openweights-0.1.0/supabase/migrations/20250116112300_fix_job_status_type.sql +24 -0
  152. openweights-0.1.0/supabase/migrations_dev/20241120094415_remote_schema.sql +161 -0
  153. openweights-0.1.0/supabase/migrations_dev/20241120161019_add_gpu_columns.sql +9 -0
  154. openweights-0.1.0/supabase/migrations_dev/20241127132826_add_docker_image.sql +8 -0
  155. openweights-0.1.0/supabase/migrations_dev/20241127153031_add_docker_image_to_workers.sql +1 -0
  156. openweights-0.1.0/supabase/migrations_dev/20241202233213_add_updated_at_columns.sql +52 -0
  157. openweights-0.1.0/supabase/migrations_dev/20241203000542_add_api_job_type.sql +2 -0
  158. openweights-0.1.0/supabase/migrations_dev/20241205000000_add_organizations.sql +206 -0
  159. openweights-0.1.0/supabase/migrations_dev/20241205000002_fix_organization_policies.sql +47 -0
  160. openweights-0.1.0/supabase/migrations_dev/20241205000003_fix_organization_member_policies.sql +24 -0
  161. openweights-0.1.0/supabase/migrations_dev/20241205000004_fix_all_organization_policies.sql +100 -0
  162. openweights-0.1.0/supabase/migrations_dev/20241205000005_add_organization_functions.sql +51 -0
  163. openweights-0.1.0/supabase/migrations_dev/20241205000006_fix_organization_function_types.sql +55 -0
  164. openweights-0.1.0/supabase/migrations_dev/20241205000007_fix_get_user_by_email_param.sql +25 -0
  165. openweights-0.1.0/supabase/migrations_dev/20241205000008_improve_get_user_by_email.sql +33 -0
  166. openweights-0.1.0/supabase/migrations_dev/20241205000009_add_invite_member_function.sql +60 -0
  167. openweights-0.1.0/supabase/migrations_dev/20241205000010_fix_invite_member_function.sql +67 -0
  168. openweights-0.1.0/supabase/migrations_dev/20241205000011_fix_get_members_function.sql +33 -0
  169. openweights-0.1.0/supabase/migrations_dev/20241205000012_fix_organization_check_functions.sql +102 -0
  170. openweights-0.1.0/supabase/migrations_dev/20241205000013_fix_all_user_id_references.sql +96 -0
  171. openweights-0.1.0/supabase/migrations_dev/20241205000014_add_storage_policies.sql +79 -0
  172. openweights-0.1.0/supabase/migrations_dev/20241205000015_migrate_existing_files.sql +40 -0
  173. openweights-0.1.0/supabase/migrations_dev/20241205000016_fix_file_migration.sql +67 -0
  174. openweights-0.1.0/supabase/migrations_dev/20241205000017_migrate_file_references.sql +76 -0
  175. openweights-0.1.0/supabase/migrations_dev/20241205000018_revert_file_references.sql +62 -0
  176. openweights-0.1.0/supabase/migrations_dev/20241205000019_verify_file_locations.sql +115 -0
  177. openweights-0.1.0/supabase/migrations_dev/20241205000020_fix_storage_locations.sql +102 -0
  178. openweights-0.1.0/supabase/migrations_dev/20241205000021_check_storage.sql +6 -0
  179. openweights-0.1.0/supabase/migrations_dev/20241205000022_fix_storage_policies.sql +71 -0
  180. openweights-0.1.0/supabase/migrations_dev/20241205000023_add_api_tokens.sql +122 -0
  181. openweights-0.1.0/supabase/migrations_dev/20241205000024_add_token_validation.sql +28 -0
  182. openweights-0.1.0/supabase/migrations_dev/20241219000001_add_long_lived_tokens.sql +40 -0
  183. openweights-0.1.0/supabase/migrations_dev/20241219000002_add_token_hash.sql +3 -0
  184. openweights-0.1.0/supabase/migrations_dev/20241219000003_update_rls_for_custom_tokens.sql +100 -0
  185. openweights-0.1.0/supabase/migrations_dev/20241219000004_update_token_auth.sql +128 -0
  186. openweights-0.1.0/supabase/migrations_dev/20241219000005_service_accounts.sql +121 -0
  187. openweights-0.1.0/supabase/migrations_dev/20241219000006_cleanup_token_tables.sql +9 -0
  188. openweights-0.1.0/supabase/migrations_dev/20241219000007_fix_token_creation.sql +60 -0
  189. openweights-0.1.0/supabase/migrations_dev/20241219000009_jwt_secret_function.sql +69 -0
  190. openweights-0.1.0/supabase/migrations_dev/20241219000010_fix_token_validation.sql +221 -0
  191. openweights-0.1.0/supabase/migrations_dev/20241219000011_fix_job_policies.sql +22 -0
  192. openweights-0.1.0/supabase/migrations_dev/20241219000012_add_get_org_function.sql +31 -0
  193. openweights-0.1.0/supabase/migrations_dev/20241219000013_fix_storage_policies.sql +119 -0
  194. openweights-0.1.0/supabase/migrations_dev/20241219000014_fix_storage_setup.sql +141 -0
  195. openweights-0.1.0/supabase/migrations_dev/20241219000015_fix_run_policies.sql +75 -0
  196. openweights-0.1.0/tests/inference_dataset_with_prefill.jsonl +3 -0
  197. openweights-0.1.0/tests/preference_dataset.jsonl +4 -0
  198. openweights-0.1.0/tests/sft_dataset.jsonl +1 -0
  199. openweights-0.1.0/tests/test_client.py +218 -0
  200. openweights-0.1.0/tests/test_run.py +145 -0
  201. openweights-0.1.0/tests/test_validation.py +133 -0
  202. openweights-0.1.0/tests/test_worker.py +49 -0
  203. openweights-0.1.0/todo.md +33 -0
@@ -0,0 +1,8 @@
1
+ .env*
2
+ **/.env*
3
+ cache/
4
+ **/cache/
5
+ .llm-cache/
6
+ **/.llm-cache/
7
+ node_modules/
8
+ **/node_modules/
@@ -0,0 +1,3 @@
1
+ OPENWEIGHTS_API_KEY=<your_openweights_api_key>
2
+ HF_ORG=longtermrisk
3
+ OW_DEFAULT_API_KEY=<optional key that will be used by vllm API deployments>
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Relevant `job_id`, `run_id`, or `worker_id`:
11
+ - eg job: ft-12345678
12
+
13
+ **Describe the bug**
14
+ A clear and concise description of what the bug is.
15
+
16
+ **To Reproduce**
17
+ Steps to reproduce the behavior:
18
+ 1. Go to '...'
19
+ 2. Click on '....'
20
+ 3. Scroll down to '....'
21
+ 4. See error
22
+
23
+ **Expected behavior**
24
+ A clear and concise description of what you expected to happen.
25
+
26
+ **Screenshots**
27
+ If applicable, add screenshots to help explain your problem.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Urgency**: one sentence re how urgent this is
11
+ **Description**
12
+ Explain the feature you'd like to see
@@ -0,0 +1,99 @@
1
+ name: "ci"
2
+ on: # rebuild any PRs and main branch changes
3
+ pull_request:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ concurrency:
9
+ group: ${{ github.repository_owner }}-${{ github.repository }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ env:
13
+ FORCE_COLOR: "1"
14
+ PYTHONUNBUFFERED: "1"
15
+
16
+ jobs:
17
+ build:
18
+ runs-on: ubuntu-latest
19
+ permissions:
20
+ contents: read
21
+ packages: write
22
+
23
+ strategy:
24
+ matrix:
25
+ python-version: ["3.10", "3.11", "3.12"]
26
+
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v4
30
+ - name: Setup PDM
31
+ uses: pdm-project/setup-pdm@v4
32
+ with:
33
+ cache: false # project doesn't use pdm lock files
34
+ python-version: ${{ matrix.python-version }}
35
+ - name: Setup UV
36
+ uses: astral-sh/setup-uv@v5
37
+ - name: Configure PDM to use UV
38
+ run: pdm config use_uv true
39
+ - name: Cache Huggingface assets
40
+ uses: actions/cache@v4
41
+ with:
42
+ key: huggingface-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }}
43
+ path: ~/.cache/huggingface
44
+ restore-keys: |
45
+ huggingface-${{ runner.os }}-${{ matrix.python-version }}-
46
+ - name: Install dependencies
47
+ run: pdm install --group dev --no-lock
48
+
49
+ # TODO: re-enable when we have pre-commit hooks
50
+ # - name: Install pre-commit hooks
51
+ # run: pdm run pre-commit install
52
+ # - name: Ensure pre-commit hooks pass
53
+ # run: pdm run pre-commit run --all-files
54
+
55
+ # TODO: tests don't currently pass due to missing torch dependency
56
+ # see: https://github.com/longtermrisk/openweights/actions/runs/13210898278/job/36883965796?pr=11#step:8:29
57
+
58
+ # - name: Run tests
59
+ # env:
60
+ # HF_TOKEN: ${{ secrets.HF_TOKEN }}
61
+ # run: pdm run python -m pytest tests
62
+
63
+ release:
64
+ needs: build
65
+ environment: pypi
66
+ permissions:
67
+ contents: write
68
+ id-token: write
69
+ # https://github.community/t/how-do-i-specify-job-dependency-running-in-another-workflow/16482
70
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, 'chore')
71
+ runs-on: ubuntu-latest
72
+ concurrency: release
73
+ steps:
74
+ - uses: actions/checkout@v4
75
+ with:
76
+ fetch-depth: 0
77
+ - uses: pdm-project/setup-pdm@v4
78
+ with:
79
+ cache: true
80
+ python-version: "3.12"
81
+ - name: build
82
+ run: pdm build
83
+ - name: Semantic Release
84
+ id: release
85
+ uses: python-semantic-release/python-semantic-release@v8.0.7
86
+ with:
87
+ github_token: ${{ secrets.GITHUB_TOKEN }}
88
+
89
+ # - name: Publish package distributions to PyPI
90
+ # uses: pypa/gh-action-pypi-publish@release/v1
91
+ # if: steps.release.outputs.released == 'true'
92
+ - name: Publish package distributions to GitHub Releases
93
+ uses: python-semantic-release/upload-to-gh-release@main
94
+ if: steps.release.outputs.released == 'true'
95
+ with:
96
+ github_token: ${{ secrets.GITHUB_TOKEN }}
97
+
98
+ # TODO: build and deploy docs to gh-pages
99
+ # do this as part of the semantic release step to ensure version is bumped
@@ -0,0 +1,24 @@
1
+ name: "manual-publish"
2
+
3
+ on:
4
+ workflow_dispatch: # Allows manual triggering
5
+
6
+ jobs:
7
+ publish:
8
+ runs-on: ubuntu-latest
9
+ environment: pypi
10
+ permissions:
11
+ id-token: write
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: pdm-project/setup-pdm@v4
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Build
21
+ run: pdm build
22
+
23
+ - name: Publish package distributions to PyPI
24
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,76 @@
1
+ logs/
2
+ openweights/dashboard/backend/backend.log
3
+ openweights/dashboard/backend/backend.pid
4
+ build-docker-in-runpod
5
+ .env
6
+ .env.dev
7
+ .env.prod
8
+ .env.ow-dev
9
+ .env.ow-migrations
10
+ openweights/dashboard/backend/.env.ow-dev
11
+ openweights/dashboard/backend/.env.ow-migrations
12
+ openweights/dashboard/frontend/.env.ow-dev
13
+ openweights/dashboard/frontend/.env.ow-migrations
14
+ artifacts/
15
+ debug/
16
+ example/.ipynb_checkpoints/
17
+ example/Untitled1.ipynb
18
+ dev.py
19
+ planb/
20
+ vulnerable-code/
21
+ openweights/client/.llm-cache
22
+ # yeaa
23
+ cache
24
+ # Bazel
25
+ /bazel-*
26
+ /bazel-bin
27
+ /bazel-genfiles
28
+ /bazel-out
29
+ /bazel-testlogs
30
+ /bazel-workspace
31
+
32
+ # Bazel symlinks
33
+ /bazel-*
34
+
35
+ # Bazel disk cache
36
+ .bazel-cache/
37
+
38
+ # Bazel IntelliJ plugin
39
+ .ijwb/
40
+
41
+ # Python
42
+ __pycache__/
43
+ *.py[cod]
44
+ *$py.class
45
+ *.so
46
+ .Python
47
+ build/
48
+ develop-eggs/
49
+ dist/
50
+ downloads/
51
+ eggs/
52
+ .eggs/
53
+ lib/
54
+ lib64/
55
+ parts/
56
+ sdist/
57
+ var/
58
+ wheels/
59
+ *.egg-info/
60
+ .installed.cfg
61
+ *.egg
62
+
63
+ # Virtual Environment
64
+ venv/
65
+ env/
66
+ ENV/
67
+
68
+ # IDE
69
+ .idea/
70
+ .vscode/
71
+ *.swp
72
+ *.swo
73
+
74
+ # OS
75
+ .DS_Store
76
+ Thumbs.db
@@ -0,0 +1 @@
1
+ /home/runner/work/openweights/openweights/.venv/bin/python
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Center on Longterm Risk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: openweights
3
+ Version: 0.1.0
4
+ Summary: An openai-like sdk for finetuning and batch inference
5
+ License: MIT
6
+ License-File: LICENSE.txt
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: diskcache
9
+ Requires-Dist: fastapi
10
+ Requires-Dist: fire
11
+ Requires-Dist: httpx>=0.24.0
12
+ Requires-Dist: huggingface-hub
13
+ Requires-Dist: openai
14
+ Requires-Dist: pyjwt
15
+ Requires-Dist: python-dotenv
16
+ Requires-Dist: runpod
17
+ Requires-Dist: scp
18
+ Requires-Dist: supabase
19
+ Requires-Dist: uvicorn
20
+ Provides-Extra: dev
21
+ Requires-Dist: black; extra == 'dev'
22
+ Requires-Dist: isort; extra == 'dev'
23
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
24
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ This repo is research code and not 100% stable. Please use github issues or contact me via email (niels dot warncke at gmail dot com) or slack when you encounter issues.
28
+
29
+ # OpenWeights
30
+ An openai-like sdk for finetuning and batch inference. Manages runpod instances for you, or you can run a [worker](openweights/worker) on your own GPU.
31
+
32
+ # Installation
33
+ Clone the repo and run `pip install -e .`.
34
+ Then add your `$OPENWEIGHTS_API_KEY` to the `.env`. You can create one via the [dashboard](https://ktf8znsjvlhidw-8124.proxy.runpod.net/).
35
+
36
+ # Quickstart
37
+ ```python
38
+ from openweights import OpenWeights
39
+ client = OpenWeights()
40
+
41
+ with open('tests/preference_dataset.jsonl', 'rb') as file:
42
+ file = client.files.create(file, purpose="preference")
43
+
44
+ job = client.fine_tuning.create(
45
+ model='unsloth/llama-3-8b-Instruct',
46
+ training_file=file['id'],
47
+ loss='dpo'
48
+ )
49
+ ```
50
+
51
+ # Client-side usage:
52
+
53
+ ## Create a finetuning job
54
+
55
+ ```python
56
+ from openweights import OpenWeights
57
+ from dotenv import load_dotenv
58
+
59
+ load_dotenv()
60
+ client = OpenWeights()
61
+
62
+ with open('tests/sft_dataset.jsonl', 'rb') as file:
63
+ file = client.files.create(file, purpose="conversations")
64
+
65
+ job = client.fine_tuning.create(
66
+ model='unsloth/llama-3-8b-Instruct',
67
+ training_file=file['id'],
68
+ requires_vram_gb=48,
69
+ loss='sft',
70
+ epochs=1
71
+ )
72
+ ```
73
+ The `job_id` is based on the params hash, which means that if you submit the same job many times, it will only run once. If you resubmit a failed or canceled job, it will reset the job status to `pending`.
74
+
75
+ More infos: [Fine-tuning Options](docs/finetuning.md)
76
+
77
+ ## Do batch inference
78
+ ```python
79
+
80
+ file = client.files.create(
81
+ file=open("mydata.jsonl", "rb"),
82
+ purpose="conversations"
83
+ )
84
+
85
+ job = client.inference.create(
86
+ model=model,
87
+ input_file_id=file['id'],
88
+ max_tokens=1000,
89
+ temperature=1,
90
+ min_tokens=600,
91
+ )
92
+ print(job)
93
+
94
+ job = client.jobs.retrieve(job['id'])
95
+ ```
96
+ Wait until job is finished, then get the output:
97
+
98
+ ```py
99
+ output_file_id = job['outputs']['file']
100
+ output = client.files.content(output_file_id).decode('utf-8')
101
+ print(output)
102
+ ```
103
+
104
+ ## Custom jobs
105
+ Maybe you'd like to use autoscaling with queues for workloads that are not currently supported. You can start a pod that is set up like a worker but doesn't start `openweights/worker/main.py` by running:
106
+ ```sh
107
+ python openweights/cluster/start_runpod.py A6000 finetuning --dev_mode=true
108
+ ```
109
+ Then develop your script and finally create a `CustomJob` like in this [example](example/custom_job).
110
+
111
+ ## Deploy a model as a temporary Openai-like API
112
+
113
+ You can deploy models as openai-like APIs in one of the following ways (sorted from highest to lowest level of abstraction)
114
+ - create chat completions via `ow.chat.completions.sync_create` or `.async_create` - this will deploy models when needed. This queues to-be-deployed models for 5 seconds and then deploys them via `ow.multi_deploy`. This client is optimized to not overload the vllm server it is talking to and caches requests on disk when a `seed` parameter is given.
115
+ - pass a list of models to deploy to `ow.multi_deploy` - this takes a list of models or lora adapters, groups them by `base_model`, and deploys all lora adapters of the same base model on one API to save runpod resources. Calls `ow.deploy` for each single deployment job. [Example](example/multi_lora_deploy.py)
116
+ - `ow.deploy` - takes a single model and optionally a list of lora adapters, then creates a job of type `api`. Returns a `openweights.client.temporary_api.TemporaryAPI` object. [Example](example/gradio_ui_with_temporary_api.py)
117
+
118
+ API jobs can never complete, they stop either because they are canceled or failed. API jobs have a timeout 15 minutes in the future when they are being created, and while a `TemporaryAPI` is alive (after `api.up()` and before `api.down()` has been called), it resets the timeout every minute. This ensures that an API is alive while the process that created it is running, at that it will automatically shut down later - but not immediately so that during debugging you don't always have to wait for deployment.
119
+
120
+
121
+ ## Using `client.deploy(model)`
122
+ ```py
123
+ from openweights import OpenWeights
124
+
125
+ client = OpenWeights()
126
+
127
+ model = 'unsloth/llama-3-8b-Instruct'
128
+ with client.deploy(model) as openai:
129
+ completion = openai.chat.completions.create(
130
+ model=model,
131
+ messages=[{"role": "user", "content": "is 9.11 > 9.9?"}]
132
+ )
133
+ print(completion.choices[0].message)
134
+ ```
135
+
136
+ More examples:
137
+ - do a [hyperparameter sweep](example/hparams_sweep.py) and [visualize the results](example/analyze_hparam_sweep.ipynb)
138
+ - [download artifacts](example/download.py) from a job and plot training
139
+ - and [more](example/)
@@ -0,0 +1,113 @@
1
+ This repo is research code and not 100% stable. Please use github issues or contact me via email (niels dot warncke at gmail dot com) or slack when you encounter issues.
2
+
3
+ # OpenWeights
4
+ An openai-like sdk for finetuning and batch inference. Manages runpod instances for you, or you can run a [worker](openweights/worker) on your own GPU.
5
+
6
+ # Installation
7
+ Clone the repo and run `pip install -e .`.
8
+ Then add your `$OPENWEIGHTS_API_KEY` to the `.env`. You can create one via the [dashboard](https://ktf8znsjvlhidw-8124.proxy.runpod.net/).
9
+
10
+ # Quickstart
11
+ ```python
12
+ from openweights import OpenWeights
13
+ client = OpenWeights()
14
+
15
+ with open('tests/preference_dataset.jsonl', 'rb') as file:
16
+ file = client.files.create(file, purpose="preference")
17
+
18
+ job = client.fine_tuning.create(
19
+ model='unsloth/llama-3-8b-Instruct',
20
+ training_file=file['id'],
21
+ loss='dpo'
22
+ )
23
+ ```
24
+
25
+ # Client-side usage:
26
+
27
+ ## Create a finetuning job
28
+
29
+ ```python
30
+ from openweights import OpenWeights
31
+ from dotenv import load_dotenv
32
+
33
+ load_dotenv()
34
+ client = OpenWeights()
35
+
36
+ with open('tests/sft_dataset.jsonl', 'rb') as file:
37
+ file = client.files.create(file, purpose="conversations")
38
+
39
+ job = client.fine_tuning.create(
40
+ model='unsloth/llama-3-8b-Instruct',
41
+ training_file=file['id'],
42
+ requires_vram_gb=48,
43
+ loss='sft',
44
+ epochs=1
45
+ )
46
+ ```
47
+ The `job_id` is based on the params hash, which means that if you submit the same job many times, it will only run once. If you resubmit a failed or canceled job, it will reset the job status to `pending`.
48
+
49
+ More infos: [Fine-tuning Options](docs/finetuning.md)
50
+
51
+ ## Do batch inference
52
+ ```python
53
+
54
+ file = client.files.create(
55
+ file=open("mydata.jsonl", "rb"),
56
+ purpose="conversations"
57
+ )
58
+
59
+ job = client.inference.create(
60
+ model=model,
61
+ input_file_id=file['id'],
62
+ max_tokens=1000,
63
+ temperature=1,
64
+ min_tokens=600,
65
+ )
66
+ print(job)
67
+
68
+ job = client.jobs.retrieve(job['id'])
69
+ ```
70
+ Wait until job is finished, then get the output:
71
+
72
+ ```py
73
+ output_file_id = job['outputs']['file']
74
+ output = client.files.content(output_file_id).decode('utf-8')
75
+ print(output)
76
+ ```
77
+
78
+ ## Custom jobs
79
+ Maybe you'd like to use autoscaling with queues for workloads that are not currently supported. You can start a pod that is set up like a worker but doesn't start `openweights/worker/main.py` by running:
80
+ ```sh
81
+ python openweights/cluster/start_runpod.py A6000 finetuning --dev_mode=true
82
+ ```
83
+ Then develop your script and finally create a `CustomJob` like in this [example](example/custom_job).
84
+
85
+ ## Deploy a model as a temporary Openai-like API
86
+
87
+ You can deploy models as openai-like APIs in one of the following ways (sorted from highest to lowest level of abstraction)
88
+ - create chat completions via `ow.chat.completions.sync_create` or `.async_create` - this will deploy models when needed. This queues to-be-deployed models for 5 seconds and then deploys them via `ow.multi_deploy`. This client is optimized to not overload the vllm server it is talking to and caches requests on disk when a `seed` parameter is given.
89
+ - pass a list of models to deploy to `ow.multi_deploy` - this takes a list of models or lora adapters, groups them by `base_model`, and deploys all lora adapters of the same base model on one API to save runpod resources. Calls `ow.deploy` for each single deployment job. [Example](example/multi_lora_deploy.py)
90
+ - `ow.deploy` - takes a single model and optionally a list of lora adapters, then creates a job of type `api`. Returns a `openweights.client.temporary_api.TemporaryAPI` object. [Example](example/gradio_ui_with_temporary_api.py)
91
+
92
+ API jobs can never complete, they stop either because they are canceled or failed. API jobs have a timeout 15 minutes in the future when they are being created, and while a `TemporaryAPI` is alive (after `api.up()` and before `api.down()` has been called), it resets the timeout every minute. This ensures that an API is alive while the process that created it is running, at that it will automatically shut down later - but not immediately so that during debugging you don't always have to wait for deployment.
93
+
94
+
95
+ ## Using `client.deploy(model)`
96
+ ```py
97
+ from openweights import OpenWeights
98
+
99
+ client = OpenWeights()
100
+
101
+ model = 'unsloth/llama-3-8b-Instruct'
102
+ with client.deploy(model) as openai:
103
+ completion = openai.chat.completions.create(
104
+ model=model,
105
+ messages=[{"role": "user", "content": "is 9.11 > 9.9?"}]
106
+ )
107
+ print(completion.choices[0].message)
108
+ ```
109
+
110
+ More examples:
111
+ - do a [hyperparameter sweep](example/hparams_sweep.py) and [visualize the results](example/analyze_hparam_sweep.ipynb)
112
+ - [download artifacts](example/download.py) from a job and plot training
113
+ - and [more](example/)
@@ -0,0 +1,144 @@
1
+ # Fine-tuning Options
2
+
3
+ OpenWeights supports several fine-tuning approaches for language models, all implemented using the Unsloth library for efficient training.
4
+
5
+ ## Supported Training Methods
6
+
7
+ ### 1. Supervised Fine-tuning (SFT)
8
+ Standard supervised fine-tuning using conversation data. This is the most basic form of fine-tuning where the model learns to generate responses based on conversation history.
9
+
10
+ ```python
11
+ from openweights import OpenWeights
12
+ client = OpenWeights()
13
+
14
+ # Upload a conversations dataset
15
+ with open('conversations.jsonl', 'rb') as file:
16
+ file = client.files.create(file, purpose="conversations")
17
+
18
+ # Start SFT training
19
+ job = client.fine_tuning.create(
20
+ model='unsloth/llama-2-7b-chat',
21
+ training_file=file['id'],
22
+ loss='sft',
23
+ epochs=1,
24
+ learning_rate=2e-5
25
+ )
26
+ ```
27
+
28
+ The conversations dataset should be in JSONL format with each line containing a "messages" field:
29
+ ```json
30
+ {"messages": [
31
+ {"role": "system", "content": "You are a helpful assistant."},
32
+ {"role": "user", "content": "What is machine learning?"},
33
+ {"role": "assistant", "content": "Machine learning is a branch of artificial intelligence..."}
34
+ ]}
35
+ ```
36
+
37
+ ### 2. Direct Preference Optimization (DPO)
38
+ DPO is a method for fine-tuning language models from preference data without using reward modeling. It directly optimizes the model to prefer chosen responses over rejected ones.
39
+
40
+ ```python
41
+ # Upload a preference dataset
42
+ with open('preferences.jsonl', 'rb') as file:
43
+ file = client.files.create(file, purpose="preference")
44
+
45
+ # Start DPO training
46
+ job = client.fine_tuning.create(
47
+ model='unsloth/llama-2-7b-chat',
48
+ training_file=file['id'],
49
+ loss='dpo',
50
+ epochs=1,
51
+ learning_rate=1e-5,
52
+ beta=0.1 # Controls the strength of the preference optimization
53
+ )
54
+ ```
55
+
56
+ ### 3. Offline Rejection Preference Optimization (ORPO)
57
+ ORPO is similar to DPO but uses a different loss function that has been shown to be more stable in some cases.
58
+
59
+ ```python
60
+ # Start ORPO training
61
+ job = client.fine_tuning.create(
62
+ model='unsloth/llama-2-7b-chat',
63
+ training_file=file['id'],
64
+ loss='orpo',
65
+ epochs=1,
66
+ learning_rate=1e-5,
67
+ beta=0.1
68
+ )
69
+ ```
70
+
71
+ The preference dataset format for both DPO and ORPO should be:
72
+ ```json
73
+ {
74
+ "prompt": [
75
+ {"role": "system", "content": "You are a helpful assistant."},
76
+ {"role": "user", "content": "What is the capital of France?"}
77
+ ],
78
+ "chosen": [
79
+ {"role": "assistant", "content": "The capital of France is Paris."}
80
+ ],
81
+ "rejected": [
82
+ {"role": "assistant", "content": "I think it's London, but I'm not sure."}
83
+ ]
84
+ }
85
+ ```
86
+
87
+ ## Common Training Parameters
88
+
89
+ All training methods support the following parameters:
90
+
91
+ - `model`: The base model to fine-tune (string)
92
+ - `training_file`: File ID of the training dataset (string)
93
+ - `test_file`: Optional file ID of the test dataset (string)
94
+ - `epochs`: Number of training epochs (int)
95
+ - `learning_rate`: Learning rate or string expression (float or string)
96
+ - `max_seq_length`: Maximum sequence length for training (int, default=2048)
97
+ - `per_device_train_batch_size`: Training batch size per device (int, default=2)
98
+ - `gradient_accumulation_steps`: Number of gradient accumulation steps (int, default=8)
99
+ - `warmup_steps`: Number of warmup steps (int, default=5)
100
+
101
+ ### LoRA Parameters
102
+
103
+ All training methods use LoRA (Low-Rank Adaptation) by default with these configurable parameters:
104
+
105
+ - `r`: LoRA attention dimension (int, default=512)
106
+ - `lora_alpha`: LoRA alpha parameter (int, default=16)
107
+ - `lora_dropout`: LoRA dropout rate (float, default=0.0)
108
+ - `target_modules`: List of modules to apply LoRA to (list of strings)
109
+ - `merge_before_push`: Whether to merge LoRA weights into base model before pushing (bool, default=True)
110
+
111
+ ## Monitoring Training
112
+
113
+ You can monitor training progress through the logged metrics:
114
+
115
+ ```python
116
+ # Get training events
117
+ events = client.events.list(job_id=job['id'])
118
+
119
+ # Get the latest values for specific metrics
120
+ latest = client.events.latest(['loss', 'learning_rate'], job_id=job['id'])
121
+ ```
122
+
123
+ ## Using the Fine-tuned Model
124
+
125
+ After training completes, you can use the model for inference:
126
+
127
+ ```python
128
+ # For merged models (merge_before_push=True)
129
+ with client.deploy(job['outputs']['model']) as openai:
130
+ completion = openai.chat.completions.create(
131
+ model=job['outputs']['model'],
132
+ messages=[{"role": "user", "content": "Hello!"}]
133
+ )
134
+
135
+ # For LoRA adapters (merge_before_push=False)
136
+ with client.deploy(
137
+ model=job['params']['model'],
138
+ lora_adapters=[job['outputs']['model']]
139
+ ) as openai:
140
+ completion = openai.chat.completions.create(
141
+ model=job['params']['model'],
142
+ messages=[{"role": "user", "content": "Hello!"}]
143
+ )
144
+ ```