Skip to content

Qwen3.5 4B#30

Merged
atdrendel merged 7 commits intomainfrom
qwen-3-5-4b
Apr 6, 2026
Merged

Qwen3.5 4B#30
atdrendel merged 7 commits intomainfrom
qwen-3-5-4b

Conversation

@atdrendel
Copy link
Copy Markdown
Contributor

@atdrendel atdrendel commented Apr 6, 2026

No description provided.

Copilot AI review requested due to automatic review settings April 6, 2026 12:33
@atdrendel atdrendel changed the title Qwen 3.5 4B Qwen3.5 4B Apr 6, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates SHLLM’s tokenizer integration and adds coverage/support scaffolding for the Qwen3.5 4B (MLX 4-bit) model variant.

Changes:

  • Update dependencies (mlx-swift-lm → 0.0.14, replace swift-transformers with swift-tokenizers) and introduce a TokenizerLoader adapter to bridge upstream Tokenizers into MLXLMCommon.Tokenizer.
  • Add Qwen3.5-4B model URL helper + a new end-to-end test suite for streaming/awaiting, tool-calls, and basic VLM image extraction.
  • Adjust truncation/tokenizer test utilities and truncation decoding to use the updated tokenizer API (decode(tokenIds:)).

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/SHLLMTests/TruncatingUserInputProcessorTests.swift Updates the test tokenizer to conform to MLXLMCommon.Tokenizer and aligns chat templating types.
Tests/SHLLMTests/Models/Qwen3_5-4BTests.swift Adds a full test suite for Qwen3.5-4B (text + tools + image extraction).
Sources/SHLLM/TruncatingUserInputProcessor.swift Switches decode call site to decode(tokenIds:) to match the new tokenizer protocol.
Sources/SHLLM/TokenizersLoader.swift Adds adapter TokenizerLoader and _Tokenizer wrapper around Tokenizers.AutoTokenizer.
Sources/SHLLM/SHLLM.swift Re-exports ToolSpec from MLXLMCommon instead of Tokenizers.
Sources/SHLLM/ModelCache.swift Loads model context using loadModel(from:using:) with the new TokenizerLoader.
Sources/SHLLM/LLM.swift Adds qwen3_5__4B directory accessor; reorganizes the SmolLM extension placement.
Package.swift Bumps mlx-swift-lm version and switches dependency to swift-tokenizers; updates target products.
Package.resolved Updates resolved dependency graph accordingly.
bin/download.sh Adds the Qwen3.5-4B-MLX-4bit model ID to the download list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +39 to +55
func applyChatTemplate(
messages: [[String: any Sendable]],
tools: [[String: any Sendable]]?,
additionalContext: [String: any Sendable]?
) throws -> [Int] {
do {
return try upstream.applyChatTemplate(
messages: messages,
tools: tools,
additionalContext: additionalContext
)
} catch let error as Tokenizers.TokenizerError
where error == .missingChatTemplate
{
throw MLXLMCommon.TokenizerError.missingChatTemplate
}
}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applyChatTemplate only translates .missingChatTemplate into MLXLMCommon.TokenizerError, but any other Tokenizers.TokenizerError (or other upstream errors) will currently escape as a Tokenizers-module error. That leaks the Tokenizers dependency through SHLLM’s public error surface; consider catching/wrapping all Tokenizers.TokenizerError cases into MLXLMCommon.TokenizerError (or a SHLLM-defined error) to keep the API consistent.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Are you working on a fix for this?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 177f0fe. applyChatTemplate now catches all Tokenizers.TokenizerError cases: .missingChatTemplate maps to MLXLMCommon.TokenizerError.missingChatTemplate, and all other cases are wrapped as NSError to prevent the Tokenizers type from leaking through SHLLM's public error surface.

Comment on lines +1 to +10
import Foundation
import MLXLMCommon
import Tokenizers

struct TokenizerLoader: MLXLMCommon.TokenizerLoader {
func load(from directory: URL) async throws -> any MLXLMCommon.Tokenizer {
let upstream = try await AutoTokenizer.from(directory: directory)
return _Tokenizer(upstream)
}
}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File name TokenizersLoader.swift doesn’t match the primary type it defines (TokenizerLoader). Renaming the file to TokenizerLoader.swift would make it easier to locate via search and keep file/type naming consistent with the rest of Sources/SHLLM (where filenames generally match their main type).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed in 8e63bfb.

Copy link
Copy Markdown
Contributor Author

@atdrendel atdrendel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well in testing.

@atdrendel atdrendel merged commit c3dc752 into main Apr 6, 2026
1 check passed
@atdrendel atdrendel deleted the qwen-3-5-4b branch April 6, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants