skypilot-nightly 1.0.0.dev20250804__py3-none-any.whl → 1.0.0.dev20250807__py3-none-any.whl

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.

Potentially problematic release.


This version of skypilot-nightly might be problematic. Click here for more details.

Files changed (151) hide show
  1. sky/__init__.py +2 -2
  2. sky/backends/cloud_vm_ray_backend.py +33 -4
  3. sky/catalog/kubernetes_catalog.py +8 -0
  4. sky/catalog/nebius_catalog.py +0 -1
  5. sky/check.py +11 -1
  6. sky/client/cli/command.py +234 -100
  7. sky/client/sdk.py +30 -9
  8. sky/client/sdk_async.py +815 -0
  9. sky/clouds/kubernetes.py +6 -1
  10. sky/clouds/nebius.py +1 -4
  11. sky/dashboard/out/404.html +1 -1
  12. sky/dashboard/out/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js +1 -0
  13. sky/dashboard/out/_next/static/chunks/1141-a8a8f1adba34c892.js +11 -0
  14. sky/dashboard/out/_next/static/chunks/1871-980a395e92633a5c.js +6 -0
  15. sky/dashboard/out/_next/static/chunks/3785.6003d293cb83eab4.js +1 -0
  16. sky/dashboard/out/_next/static/chunks/{3698-7874720877646365.js → 3850-ff4a9a69d978632b.js} +1 -1
  17. sky/dashboard/out/_next/static/chunks/4725.29550342bd53afd8.js +1 -0
  18. sky/dashboard/out/_next/static/chunks/{4937.d6bf67771e353356.js → 4937.a2baa2df5572a276.js} +1 -1
  19. sky/dashboard/out/_next/static/chunks/6130-2be46d70a38f1e82.js +1 -0
  20. sky/dashboard/out/_next/static/chunks/6601-3e21152fe16da09c.js +1 -0
  21. sky/dashboard/out/_next/static/chunks/{691.6d99cbfba347cebf.js → 691.5eeedf82cc243343.js} +1 -1
  22. sky/dashboard/out/_next/static/chunks/6989-6129c1cfbcf51063.js +1 -0
  23. sky/dashboard/out/_next/static/chunks/6990-0f886f16e0d55ff8.js +1 -0
  24. sky/dashboard/out/_next/static/chunks/8056-019615038d6ce427.js +1 -0
  25. sky/dashboard/out/_next/static/chunks/8252.62b0d23aed618bb2.js +16 -0
  26. sky/dashboard/out/_next/static/chunks/8969-318c3dca725e8e5d.js +1 -0
  27. sky/dashboard/out/_next/static/chunks/{9025.7937c16bc8623516.js → 9025.a1bef12d672bb66d.js} +1 -1
  28. sky/dashboard/out/_next/static/chunks/9159-11421c0f2909236f.js +1 -0
  29. sky/dashboard/out/_next/static/chunks/9360.85b0b1b4054574dd.js +31 -0
  30. sky/dashboard/out/_next/static/chunks/9666.cd4273f2a5c5802c.js +1 -0
  31. sky/dashboard/out/_next/static/chunks/{9847.4c46c5e229c78704.js → 9847.757720f3b40c0aa5.js} +1 -1
  32. sky/dashboard/out/_next/static/chunks/{9984.78ee6d2c6fa4b0e8.js → 9984.c5564679e467d245.js} +1 -1
  33. sky/dashboard/out/_next/static/chunks/pages/{_app-a67ae198457b9886.js → _app-1e6de35d15a8d432.js} +1 -1
  34. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-6fd1d2d8441aa54b.js +11 -0
  35. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-155d477a6c3e04e2.js +1 -0
  36. sky/dashboard/out/_next/static/chunks/pages/clusters-b30460f683e6ba96.js +1 -0
  37. sky/dashboard/out/_next/static/chunks/pages/{config-8620d099cbef8608.js → config-dfb9bf07b13045f4.js} +1 -1
  38. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-13d53fffc03ccb52.js +1 -0
  39. sky/dashboard/out/_next/static/chunks/pages/infra-fc9222e26c8e2f0d.js +1 -0
  40. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-154f55cf8af55be5.js +11 -0
  41. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-f5ccf5d39d87aebe.js +21 -0
  42. sky/dashboard/out/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js +1 -0
  43. sky/dashboard/out/_next/static/chunks/pages/users-7ed36e44e779d5c7.js +1 -0
  44. sky/dashboard/out/_next/static/chunks/pages/volumes-c9695d657f78b5dc.js +1 -0
  45. sky/dashboard/out/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js +1 -0
  46. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-f72f73bcef9541dc.js +1 -0
  47. sky/dashboard/out/_next/static/chunks/pages/workspaces-8f67be60165724cc.js +1 -0
  48. sky/dashboard/out/_next/static/chunks/webpack-76efbdad99742559.js +1 -0
  49. sky/dashboard/out/_next/static/css/4614e06482d7309e.css +3 -0
  50. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  51. sky/dashboard/out/clusters/[cluster].html +1 -1
  52. sky/dashboard/out/clusters.html +1 -1
  53. sky/dashboard/out/config.html +1 -1
  54. sky/dashboard/out/index.html +1 -1
  55. sky/dashboard/out/infra/[context].html +1 -1
  56. sky/dashboard/out/infra.html +1 -1
  57. sky/dashboard/out/jobs/[job].html +1 -1
  58. sky/dashboard/out/jobs/pools/[pool].html +1 -0
  59. sky/dashboard/out/jobs.html +1 -1
  60. sky/dashboard/out/users.html +1 -1
  61. sky/dashboard/out/volumes.html +1 -1
  62. sky/dashboard/out/workspace/new.html +1 -1
  63. sky/dashboard/out/workspaces/[name].html +1 -1
  64. sky/dashboard/out/workspaces.html +1 -1
  65. sky/global_user_state.py +14 -2
  66. sky/jobs/__init__.py +2 -0
  67. sky/jobs/client/sdk.py +43 -2
  68. sky/jobs/client/sdk_async.py +135 -0
  69. sky/jobs/server/core.py +48 -1
  70. sky/jobs/server/server.py +52 -3
  71. sky/jobs/state.py +5 -1
  72. sky/jobs/utils.py +3 -1
  73. sky/provision/kubernetes/utils.py +30 -4
  74. sky/provision/nebius/instance.py +1 -0
  75. sky/provision/nebius/utils.py +9 -1
  76. sky/schemas/db/global_user_state/002_add_workspace_to_cluster_history.py +35 -0
  77. sky/schemas/db/spot_jobs/003_pool_hash.py +34 -0
  78. sky/serve/client/impl.py +85 -1
  79. sky/serve/client/sdk.py +16 -47
  80. sky/serve/client/sdk_async.py +130 -0
  81. sky/serve/constants.py +3 -1
  82. sky/serve/controller.py +6 -3
  83. sky/serve/load_balancer.py +3 -1
  84. sky/serve/serve_state.py +93 -5
  85. sky/serve/serve_utils.py +200 -67
  86. sky/serve/server/core.py +13 -197
  87. sky/serve/server/impl.py +261 -23
  88. sky/serve/service.py +15 -3
  89. sky/server/auth/__init__.py +0 -0
  90. sky/server/auth/authn.py +46 -0
  91. sky/server/auth/oauth2_proxy.py +185 -0
  92. sky/server/common.py +119 -21
  93. sky/server/constants.py +1 -1
  94. sky/server/daemons.py +60 -11
  95. sky/server/requests/executor.py +5 -3
  96. sky/server/requests/payloads.py +19 -0
  97. sky/server/rest.py +114 -0
  98. sky/server/server.py +44 -40
  99. sky/setup_files/dependencies.py +2 -0
  100. sky/skylet/constants.py +1 -1
  101. sky/skylet/events.py +5 -1
  102. sky/skylet/skylet.py +3 -1
  103. sky/task.py +61 -21
  104. sky/templates/kubernetes-ray.yml.j2 +9 -0
  105. sky/templates/nebius-ray.yml.j2 +1 -0
  106. sky/templates/sky-serve-controller.yaml.j2 +1 -0
  107. sky/usage/usage_lib.py +8 -6
  108. sky/utils/annotations.py +8 -3
  109. sky/utils/common_utils.py +11 -1
  110. sky/utils/controller_utils.py +7 -0
  111. sky/utils/db/migration_utils.py +2 -2
  112. sky/utils/rich_utils.py +120 -0
  113. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/METADATA +22 -13
  114. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/RECORD +120 -112
  115. sky/client/sdk.pyi +0 -300
  116. sky/dashboard/out/_next/static/KiGGm4fK0CpmN6BT17jkh/_buildManifest.js +0 -1
  117. sky/dashboard/out/_next/static/chunks/1043-928582d4860fef92.js +0 -1
  118. sky/dashboard/out/_next/static/chunks/1141-3f10a5a9f697c630.js +0 -11
  119. sky/dashboard/out/_next/static/chunks/1664-22b00e32c9ff96a4.js +0 -1
  120. sky/dashboard/out/_next/static/chunks/1871-7e17c195296e2ea9.js +0 -6
  121. sky/dashboard/out/_next/static/chunks/2003.f90b06bb1f914295.js +0 -1
  122. sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +0 -1
  123. sky/dashboard/out/_next/static/chunks/3785.95524bc443db8260.js +0 -1
  124. sky/dashboard/out/_next/static/chunks/4725.42f21f250f91f65b.js +0 -1
  125. sky/dashboard/out/_next/static/chunks/4869.18e6a4361a380763.js +0 -16
  126. sky/dashboard/out/_next/static/chunks/5230-f3bb2663e442e86c.js +0 -1
  127. sky/dashboard/out/_next/static/chunks/6601-234b1cf963c7280b.js +0 -1
  128. sky/dashboard/out/_next/static/chunks/6989-983d3ae7a874de98.js +0 -1
  129. sky/dashboard/out/_next/static/chunks/6990-08b2a1cae076a943.js +0 -1
  130. sky/dashboard/out/_next/static/chunks/8969-9a8cca241b30db83.js +0 -1
  131. sky/dashboard/out/_next/static/chunks/938-40d15b6261ec8dc1.js +0 -1
  132. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-fa63e8b1d203f298.js +0 -11
  133. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-9e7df5fc761c95a7.js +0 -1
  134. sky/dashboard/out/_next/static/chunks/pages/clusters-956ad430075efee8.js +0 -1
  135. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-9cfd875eecb6eaf5.js +0 -1
  136. sky/dashboard/out/_next/static/chunks/pages/infra-0fbdc9072f19fbe2.js +0 -1
  137. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-6c5af4c86e6ab3d3.js +0 -11
  138. sky/dashboard/out/_next/static/chunks/pages/jobs-6393a9edc7322b54.js +0 -1
  139. sky/dashboard/out/_next/static/chunks/pages/users-34d6bb10c3b3ee3d.js +0 -1
  140. sky/dashboard/out/_next/static/chunks/pages/volumes-225c8dae0634eb7f.js +0 -1
  141. sky/dashboard/out/_next/static/chunks/pages/workspace/new-92f741084a89e27b.js +0 -1
  142. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-4d41c9023287f59a.js +0 -1
  143. sky/dashboard/out/_next/static/chunks/pages/workspaces-e4cb7e97d37e93ad.js +0 -1
  144. sky/dashboard/out/_next/static/chunks/webpack-13145516b19858fb.js +0 -1
  145. sky/dashboard/out/_next/static/css/b3227360726f12eb.css +0 -3
  146. /sky/dashboard/out/_next/static/{KiGGm4fK0CpmN6BT17jkh → YAirOGsV1z6B2RJ0VIUmD}/_ssgManifest.js +0 -0
  147. /sky/dashboard/out/_next/static/chunks/{6135-d0e285ac5f3f2485.js → 6135-85426374db04811e.js} +0 -0
  148. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/WHEEL +0 -0
  149. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/entry_points.txt +0 -0
  150. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/licenses/LICENSE +0 -0
  151. {skypilot_nightly-1.0.0.dev20250804.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/top_level.txt +0 -0
sky/utils/rich_utils.py CHANGED
@@ -15,11 +15,13 @@ from sky.utils import message_utils
15
15
  from sky.utils import rich_console_utils
16
16
 
17
17
  if typing.TYPE_CHECKING:
18
+ import aiohttp
18
19
  import requests
19
20
  import rich.console as rich_console
20
21
  else:
21
22
  requests = adaptors_common.LazyImport('requests')
22
23
  rich_console = adaptors_common.LazyImport('rich.console')
24
+ aiohttp = adaptors_common.LazyImport('aiohttp')
23
25
 
24
26
  GeneralStatus = Union['rich_console.Status', 'EncodedStatus']
25
27
 
@@ -398,3 +400,121 @@ def decode_rich_status(
398
400
  finally:
399
401
  if decoding_status is not None:
400
402
  decoding_status.__exit__(None, None, None)
403
+
404
+
405
+ async def decode_rich_status_async(
406
+ response: 'aiohttp.ClientResponse'
407
+ ) -> typing.AsyncIterator[Optional[str]]:
408
+ """Async version of rich_utils.decode_rich_status that decodes rich status
409
+ messages from an aiohttp response.
410
+
411
+ Args:
412
+ response: The aiohttp response.
413
+
414
+ Yields:
415
+ Optional[str]: Decoded lines or None for control messages.
416
+ """
417
+ decoding_status = None
418
+ try:
419
+ last_line = ''
420
+ # Buffer to store incomplete UTF-8 bytes between chunks
421
+ undecoded_buffer = b''
422
+
423
+ # Iterate over the response content in chunks
424
+ async for chunk in response.content.iter_chunked(8192):
425
+ if chunk is None:
426
+ return
427
+
428
+ # Append the new chunk to any leftover bytes from previous iteration
429
+ current_bytes = undecoded_buffer + chunk
430
+ undecoded_buffer = b''
431
+
432
+ # Try to decode the combined bytes
433
+ try:
434
+ encoded_msg = current_bytes.decode('utf-8')
435
+ except UnicodeDecodeError as e:
436
+ # Check if this is potentially an incomplete sequence at the end
437
+ if e.start > 0:
438
+ # Decode the valid part
439
+ encoded_msg = current_bytes[:e.start].decode('utf-8')
440
+
441
+ # Check if the remaining bytes are likely a partial char
442
+ # or actually invalid UTF-8
443
+ remaining_bytes = current_bytes[e.start:]
444
+ if len(remaining_bytes) < 4: # Max UTF-8 char is 4 bytes
445
+ # Likely incomplete - save for next chunk
446
+ undecoded_buffer = remaining_bytes
447
+ else:
448
+ # Likely invalid - replace with replacement character
449
+ encoded_msg += remaining_bytes.decode('utf-8',
450
+ errors='replace')
451
+ undecoded_buffer = b''
452
+ else:
453
+ # Error at the very beginning of the buffer - invalid UTF-8
454
+ encoded_msg = current_bytes.decode('utf-8',
455
+ errors='replace')
456
+ undecoded_buffer = b''
457
+
458
+ lines = encoded_msg.splitlines(keepends=True)
459
+
460
+ # Skip processing if lines is empty to avoid IndexError
461
+ if not lines:
462
+ continue
463
+
464
+ lines[0] = last_line + lines[0]
465
+ last_line = lines[-1]
466
+ # If the last line is not ended with `\r` or `\n` (with ending
467
+ # spaces stripped), it means the last line is not a complete line.
468
+ # We keep the last line in the buffer and continue.
469
+ if (not last_line.strip(' ').endswith('\r') and
470
+ not last_line.strip(' ').endswith('\n')):
471
+ lines = lines[:-1]
472
+ else:
473
+ # Reset the buffer for the next line, as the last line is a
474
+ # complete line.
475
+ last_line = ''
476
+
477
+ for line in lines:
478
+ if line.endswith('\r\n'):
479
+ # Replace `\r\n` with `\n`, as printing a line ends with
480
+ # `\r\n` in linux will cause the line to be empty.
481
+ line = line[:-2] + '\n'
482
+ is_payload, line = message_utils.decode_payload(
483
+ line, raise_for_mismatch=False)
484
+ control = None
485
+ if is_payload:
486
+ control, encoded_status = Control.decode(line)
487
+ if control is None:
488
+ yield line
489
+ continue
490
+
491
+ if control == Control.RETRY:
492
+ raise exceptions.RequestInterruptedError(
493
+ 'Streaming interrupted. Please retry.')
494
+ # control is not None, i.e. it is a rich status control message.
495
+ # In async context, we'll handle rich status controls normally
496
+ # since async typically runs in main thread
497
+ if control == Control.INIT:
498
+ decoding_status = client_status(encoded_status)
499
+ else:
500
+ if decoding_status is None:
501
+ # status may not be initialized if a user use --tail for
502
+ # sky api logs.
503
+ continue
504
+ assert decoding_status is not None, (
505
+ f'Rich status not initialized: {line}')
506
+ if control == Control.UPDATE:
507
+ decoding_status.update(encoded_status)
508
+ elif control == Control.STOP:
509
+ decoding_status.stop()
510
+ elif control == Control.EXIT:
511
+ decoding_status.__exit__(None, None, None)
512
+ elif control == Control.START:
513
+ decoding_status.start()
514
+ elif control == Control.HEARTBEAT:
515
+ # Heartbeat is not displayed to the user, so we do not
516
+ # need to update the status.
517
+ pass
518
+ finally:
519
+ if decoding_status is not None:
520
+ decoding_status.__exit__(None, None, None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20250804
3
+ Version: 1.0.0.dev20250807
4
4
  Summary: SkyPilot: Run AI on Any Infra — Unified, Faster, Cheaper.
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -57,6 +57,7 @@ Requires-Dist: pyjwt
57
57
  Requires-Dist: gitpython
58
58
  Requires-Dist: types-paramiko
59
59
  Requires-Dist: alembic
60
+ Requires-Dist: aiohttp
60
61
  Provides-Extra: aws
61
62
  Requires-Dist: awscli>=1.27.10; extra == "aws"
62
63
  Requires-Dist: botocore>=1.29.10; extra == "aws"
@@ -132,6 +133,7 @@ Requires-Dist: casbin; extra == "server"
132
133
  Requires-Dist: sqlalchemy_adapter; extra == "server"
133
134
  Requires-Dist: passlib; extra == "server"
134
135
  Requires-Dist: pyjwt; extra == "server"
136
+ Requires-Dist: aiohttp; extra == "server"
135
137
  Provides-Extra: all
136
138
  Requires-Dist: awscli>=1.27.10; extra == "all"
137
139
  Requires-Dist: botocore>=1.29.10; extra == "all"
@@ -186,6 +188,7 @@ Requires-Dist: casbin; extra == "all"
186
188
  Requires-Dist: sqlalchemy_adapter; extra == "all"
187
189
  Requires-Dist: passlib; extra == "all"
188
190
  Requires-Dist: pyjwt; extra == "all"
191
+ Requires-Dist: aiohttp; extra == "all"
189
192
  Dynamic: author
190
193
  Dynamic: classifier
191
194
  Dynamic: description
@@ -235,6 +238,7 @@ Dynamic: summary
235
238
  ----
236
239
 
237
240
  :fire: *News* :fire:
241
+ - [Aug 2025] Run and serve **OpenAI GPT-OSS models** (gpt-oss-120b, gpt-oss-20b) with one command on any infra: [**example**](./llm/gpt-oss/)
238
242
  - [Jul 2025] Run distributed **RL training for LLMs** with Verl (PPO, GRPO) on any cloud: [**example**](./llm/verl/)
239
243
  - [Jul 2025] 🎉 SkyPilot v0.10.0 released! [**blog post**](https://blog.skypilot.co/announcing-skypilot-0.10.0/), [**release notes**](https://github.com/skypilot-org/skypilot/releases/tag/v0.10.0)
240
244
  - [Jul 2025] Finetune **Llama4** on any distributed cluster/cloud: [**example**](./llm/llama-4-finetuning/)
@@ -252,12 +256,18 @@ Dynamic: summary
252
256
 
253
257
  ----
254
258
 
255
- SkyPilot is an open-source framework for running AI and batch workloads on any infra.
259
+ SkyPilot is an open-source system for running AI and batch workloads on any infra.
256
260
 
257
261
  SkyPilot **is easy to use for AI users**:
258
- - Quickly spin up compute on your own infra
262
+ - Quickly spin up jobs on your own infra
259
263
  - Environment and job as code — simple and portable
260
- - Easy job management: queue, run, and auto-recover many jobs
264
+ - Easy management: queue, run, and auto-recover many jobs
265
+
266
+ SkyPilot **makes Kubernetes easy for AI teams**:
267
+
268
+ - Slurm-like ease of use, cloud-native robustness
269
+ - Local dev experience on K8s: SSH into pods, sync code, or connect IDE
270
+ - Turbocharge your clusters: gang scheduling, multi-cluster, and scaling
261
271
 
262
272
  SkyPilot **unifies multiple clusters, clouds, and hardware**:
263
273
  - One interface to use reserved GPUs, Kubernetes clusters, or 16+ clouds
@@ -305,7 +315,7 @@ You can find our documentation [here](https://docs.skypilot.co/).
305
315
 
306
316
  A SkyPilot task specifies: resource requirements, data to be synced, setup commands, and the task commands.
307
317
 
308
- Once written in this [**unified interface**](https://docs.skypilot.co/en/latest/reference/yaml-spec.html) (YAML or Python API), the task can be launched on any available cloud. This avoids vendor lock-in, and allows easily moving jobs to a different provider.
318
+ Once written in this [**unified interface**](https://docs.skypilot.co/en/latest/reference/yaml-spec.html) (YAML or Python API), the task can be launched on any available infra (Kubernetes, cloud, etc.). This avoids vendor lock-in, and allows easily moving jobs to a different provider.
309
319
 
310
320
  Paste the following into a file `my_task.yaml`:
311
321
 
@@ -343,12 +353,11 @@ sky launch my_task.yaml
343
353
  ```
344
354
 
345
355
  SkyPilot then performs the heavy-lifting for you, including:
346
- 1. Find the lowest priced VM instance type across different clouds
347
- 2. Provision the VM, with auto-failover if the cloud returned capacity errors
348
- 3. Sync the local `workdir` to the VM
349
- 4. Run the task's `setup` commands to prepare the VM for running the task
350
- 5. Run the task's `run` commands
351
-
356
+ 1. Find the cheapest & available infra across your clusters or clouds
357
+ 2. Provision the GPUs (pods or VMs), with auto-failover if the infra returned capacity errors
358
+ 3. Sync your local `workdir` to the provisioned cluster
359
+ 4. Auto-install dependencies by running the task's `setup` commands
360
+ 5. Run the task's `run` commands, and stream logs
352
361
 
353
362
  See [Quickstart](https://docs.skypilot.co/en/latest/getting-started/quickstart.html) to get started with SkyPilot.
354
363
 
@@ -360,13 +369,13 @@ Latest featured examples:
360
369
 
361
370
  | Task | Examples |
362
371
  |----------|----------|
363
- | Training | [PyTorch](https://docs.skypilot.co/en/latest/getting-started/tutorial.html), [DeepSpeed](https://docs.skypilot.co/en/latest/examples/training/deepspeed.html), [Finetune Llama 3](https://docs.skypilot.co/en/latest/examples/training/llama-3_1-finetuning.html), [NeMo](https://docs.skypilot.co/en/latest/examples/training/nemo.html), [Ray](https://docs.skypilot.co/en/latest/examples/training/ray.html), [Unsloth](https://docs.skypilot.co/en/latest/examples/training/unsloth.html), [Jax/TPU](https://docs.skypilot.co/en/latest/examples/training/tpu.html) |
372
+ | Training | [Verl](https://docs.skypilot.co/en/latest/examples/training/verl.html), [Finetune Llama 4](https://docs.skypilot.co/en/latest/examples/training/llama-4-finetuning.html), [PyTorch](https://docs.skypilot.co/en/latest/getting-started/tutorial.html), [DeepSpeed](https://docs.skypilot.co/en/latest/examples/training/deepspeed.html), [NeMo](https://docs.skypilot.co/en/latest/examples/training/nemo.html), [Ray](https://docs.skypilot.co/en/latest/examples/training/ray.html), [Unsloth](https://docs.skypilot.co/en/latest/examples/training/unsloth.html), [Jax/TPU](https://docs.skypilot.co/en/latest/examples/training/tpu.html) |
364
373
  | Serving | [vLLM](https://docs.skypilot.co/en/latest/examples/serving/vllm.html), [SGLang](https://docs.skypilot.co/en/latest/examples/serving/sglang.html), [Ollama](https://docs.skypilot.co/en/latest/examples/serving/ollama.html) |
365
374
  | Models | [DeepSeek-R1](https://docs.skypilot.co/en/latest/examples/models/deepseek-r1.html), [Llama 3](https://docs.skypilot.co/en/latest/examples/models/llama-3.html), [CodeLlama](https://docs.skypilot.co/en/latest/examples/models/codellama.html), [Qwen](https://docs.skypilot.co/en/latest/examples/models/qwen.html), [Mixtral](https://docs.skypilot.co/en/latest/examples/models/mixtral.html) |
366
375
  | AI apps | [RAG](https://docs.skypilot.co/en/latest/examples/applications/rag.html), [vector databases](https://docs.skypilot.co/en/latest/examples/applications/vector_database.html) (ChromaDB, CLIP) |
367
376
  | Common frameworks | [Airflow](https://docs.skypilot.co/en/latest/examples/frameworks/airflow.html), [Jupyter](https://docs.skypilot.co/en/latest/examples/frameworks/jupyter.html) |
368
377
 
369
- Source files and more examples can be found in [`llm/`](https://github.com/skypilot-org/skypilot/tree/master/llm) and [`examples/`](https://github.com/skypilot-org/skypilot/tree/master/examples).
378
+ Source files can be found in [`llm/`](https://github.com/skypilot-org/skypilot/tree/master/llm) and [`examples/`](https://github.com/skypilot-org/skypilot/tree/master/examples).
370
379
 
371
380
  ## More information
372
381
  To learn more, see [SkyPilot Overview](https://docs.skypilot.co/en/latest/overview.html), [SkyPilot docs](https://docs.skypilot.co/en/latest/), and [SkyPilot blog](https://blog.skypilot.co/).