Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 1.2.33 (2026-11-08)

Full Changelog: [v1.2.32...v1.2.33](https://github.com/fw-ai-external/python-sdk/compare/v1.2.32...v1.2.33)

### Features
* **deployments, models, deployed models, deployment shapes:** return `created_by` (the creator's email) on `Deployment`, `Model`, `DeployedModel` and `DeploymentShape`. Only members of the resource's own account see it; for other callers it is empty.
* **training-sdk:** support dedicated LoRA full-weight synchronization over RDMA, with capability negotiation and managed provisioning checks
* **training-sdk:** load reviewed Kimi K3 and K3.1 tokenizers without executing checkpoint Python, with shared vocabulary and distinct packaged chat encoders.

### Bug Fixes
* **training-sdk:** preserve message sampling, saved fast-tokenizer overrides and chat-profile save/reload behavior on code-free Kimi loading paths.
* **training-sdk:** follow the November 5 Kimi K3.1 release encoder, which rejects the invalid `medium` thinking effort without changing vocabulary or image-token IDs.
* **training-sdk:** keep DeepSeek V4.1 tokenizer and renderer loading in installed code, including explicit base-model context and opaque managed tokenizer paths.

## 1.2.32 (2026-11-05)

Full Changelog: [v1.2.31...v1.2.32](https://github.com/fw-ai-external/python-sdk/compare/v1.2.31...v1.2.32)
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "fireworks-ai"
version = "1.2.32"
version = "1.2.33"
description = "The official Python library for the fireworks API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down Expand Up @@ -65,9 +65,9 @@ training-sdk = [
training = [
"fireworks-ai[training-sdk]",
"torch>=2.0.0",
"transformers",
"transformers>=4.57.6,<6",
"datasets",
"tiktoken",
"tiktoken>=0.12.0",
"numpy",
"wandb",
]
Expand Down
16 changes: 8 additions & 8 deletions src/fireworks/training/sdk/_core/_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,15 @@ def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]:

def _iter_chunks(self, iterator: Iterator[bytes]) -> Iterator[bytes]:
"""Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks"""
data = b""
data = bytearray()
for chunk in iterator:
for line in chunk.splitlines(keepends=True):
data += line
if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")):
yield data
data = b""
yield bytes(data)
data = bytearray()
if data:
yield data
yield bytes(data)

async def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]:
"""Given an iterator that yields raw binary data, iterate over it & yield every event encountered"""
Expand All @@ -170,15 +170,15 @@ async def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[Ser

async def _aiter_chunks(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[bytes]:
"""Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks"""
data = b""
data = bytearray()
async for chunk in iterator:
for line in chunk.splitlines(keepends=True):
data += line
if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")):
yield data
data = b""
yield bytes(data)
data = bytearray()
if data:
yield data
yield bytes(data)

def decode(self, line: str) -> ServerSentEvent | None:
# See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from fireworks.training.sdk import types
from fireworks.training.sdk._core._utils import lru_cache
from fireworks.training.sdk._core.lib.sidecar import SidecarRPC, SidecarHandle, create_sidecar_handle
from fireworks.training.sdk.tokenizer_identity import is_deepseek_v4_model_name, requires_code_free_tokenizer_loading
from fireworks.training.sdk.tokenizer_identity import (
is_code_free_model_name,
is_kimi_k3_k31_model_name,
is_kimi_k3_k31_tokenizer_source,
requires_code_free_tokenizer_loading,
)
from fireworks.training.sdk._core.lib.telemetry import Telemetry, capture_exceptions
from fireworks.training.sdk._core.lib.retry_handler import RetryConfig, RetryHandler
from fireworks.training.sdk._core.lib.api_future_impl import QueueState, QueueStateObserver, _APIFuture
Expand Down Expand Up @@ -539,11 +544,23 @@ def _load_tokenizer_from_model_info(
}

if (
is_deepseek_v4_model_name(model_name)
or model_arch == "DeepseekV4ForCausalLM"
is_kimi_k3_k31_model_name(model_name)
or model_arch in ("KimiK3ForConditionalGeneration", "KimiK31ForConditionalGeneration")
or is_kimi_k3_k31_tokenizer_source(tokenizer_id, revision=kwargs.get("revision"))
):
# Recognized reviewed Kimi K3/K3.1 data: build the id-identical fast
# tokenizer from reviewed installed code. Checkpoint Python (the
# auto_map TikTokenTokenizer) is never imported.
from fireworks.training.sdk.kimi_native_tokenizer import load_native_tokenizer

return load_native_tokenizer(tokenizer_id, revision=kwargs.get("revision"))

if (
is_code_free_model_name(model_name)
or model_arch in {"DeepseekV4ForCausalLM", "DeepseekV41ForCausalLM", "DeepseekV41ForConditionalGeneration"}
or requires_code_free_tokenizer_loading(tokenizer_id, revision=kwargs.get("revision"))
):
# Recognized official DeepSeek V4 data ships no remote code; an
# Reviewed DeepSeek V4/V4.1 data ships no remote code; an
# explicit False resolves the identical tokenizer class and keeps any
# checkpoint-staged Python inert.
kwargs["trust_remote_code"] = False
Expand Down
8 changes: 4 additions & 4 deletions src/fireworks/training/sdk/_sse.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ def __init__(self) -> None:
@staticmethod
async def _aiter_chunks(stream: Any) -> Any:
"""Reassemble raw bytes into SSE chunks (delimited by blank lines)."""
buf = b""
buf = bytearray()
async for raw in stream.aiter_bytes():
for line in raw.splitlines(keepends=True):
buf += line
if buf.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")):
yield buf
buf = b""
yield bytes(buf)
buf = bytearray()
if buf:
yield buf
yield bytes(buf)

async def aiter_events(self, response: Any) -> Any:
"""Yield :class:`_SSEEvent` objects from an ``httpx.Response``."""
Expand Down
1 change: 1 addition & 0 deletions src/fireworks/training/sdk/_vendored/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Reviewed runtime assets; no checkpoint module is imported."""
52 changes: 52 additions & 0 deletions src/fireworks/training/sdk/_vendored/kimi_k3/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Kimi K3 License

Copyright (c) 2026 Moonshot AI

Permission is hereby granted, free of charge, to any person (the "Licensee")
obtaining a copy of this software — including the model weights, parameters,
configuration files, inference and training code, and associated documentation
(collectively, the "Software") — to deal in the Software without restriction.
This includes, without limitation, the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software; to run,
deploy, fine-tune, or otherwise modify the Software and create derivative works
from it; and to permit persons to whom the Software is furnished to do so, in
each case subject to the following conditions:

1. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. Licensee's use of the
Software must comply with applicable laws and regulations.

2. "Model as a Service" means giving a third party access to language model
inference or fine-tuning (e.g., via API) in a manner that allows such third
party to exercise meaningful control over the inputs, parameters, or training
data. This does not include (a) end-user products with model capabilities solely
embedded within specific features or harnesses, or (b) mere relaying of requests
to models hosted by others.

If the Licensee or any of its affiliates operates a Model as a Service business,
and the aggregate revenue of the Licensee and its affiliates exceeds 20 million
US dollars (or the equivalent in other currencies) in total over any consecutive
12 months, the Licensee must enter into a separate agreement with Moonshot AI
before using the Software or its derivative works for any commercial purpose.

3. If the Software (or any derivative works thereof) is used for any of the
Licensee's commercial products or services that have more than 100 million
monthly active users, or more than 20 million US dollars (or equivalent in other
currencies) in monthly revenue, "Kimi K3" must be prominently displayed on the
user interface of such product or service.

4. The requirements set forth in Sections 2 and 3 do not apply to: (a) internal
use of the Software, defined as any use that does not make the Software, its
outputs, or its underlying capabilities available to third parties; or (b) any
use of the Software accessed through Moonshot AI's official products or
certified inference partners.

5. THE SOFTWARE AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED ON AN “AS IS”
BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
AND NONINFRINGEMENT. IN NO EVENT SHALL MOONSHOT AI OR ITS AFFILIATES OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

For any questions regarding this license, please contact <license@moonshot.ai>.
42 changes: 42 additions & 0 deletions src/fireworks/training/sdk/_vendored/kimi_k3/PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SDK packaged-encoder adaptation

The manifest below describes the reviewed upstream source. The SDK copy differs only by the existing Ruff import order and, for K3, renaming the unused loop index to `_message_index`. No template/token semantics change and no lint rule is disabled. Regenerate using the tokenizer snapshot generator.

SDK packaged SHA-256: `b04b6ecd223d0b8519c5926f095f9531e97396c915595674effcc39fd4658323`.

## Original source manifest

# Vendored Kimi K3 encoder

`encoding_k3.py` is a byte-for-byte copy of the upstream Kimi K3 XTML chat
encoder, incorporated as reviewed package source so that renderer tokenization
never fetches or executes checkpoint Python at runtime.

| Field | Value |
|---|---|
| Upstream file | `encoding_k3.py` |
| Source repository | `moonshotai/Kimi-K3` |
| Source revision | `301be1b88c89c0d3a763da6301352cb8fe399e90` |
| sha256 | `b9cb7ae100fed34b9337f80dacee5abbf7e261fe9b74bc0e76366701d46f5333` |
| License | Kimi K3 License (see `LICENSE`, copyright 2026 Moonshot AI) |
| Retrieved | 2026-11-05 |

The sha256 above is identical to the constant `KIMI_K3_ENCODER_SHA256` in
`training/renderer/kimi_k3.py`; a unit test asserts the vendored file still
hashes to it.

Static inspection at incorporation (26311 bytes): imports limited to
`__future__`, `json`, `dataclasses`, `typing`; no I/O, no `exec`/`eval`, no
subprocess, no network, no third-party dependencies.

Do not edit this file. To move to a newer upstream revision: download the
exact new revision, verify its sha256, statically inspect it, replace this
file, and update `KIMI_K3_ENCODER_SHA256` and this document in the same
change.

Note: the Kimi K3.1 encoder is vendored separately under
`training/renderer/tito/_vendored/kimi_k31/` (pin
`367f0a7ab8800f78f7e09dc31e58544ee7fc46eea992ea05b32d53506a921cc5`). The two
encoders are distinct rendering contracts -- K3.1 renders non-string tool
arguments from their JSON literal bytes --
and must not be aliased.
1 change: 1 addition & 0 deletions src/fireworks/training/sdk/_vendored/kimi_k3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Kimi K3 XTML chat encoder, vendored verbatim (see PROVENANCE.md)."""
Loading
Loading