Skip to content

Conversation

@thc1006
Copy link

@thc1006 thc1006 commented Dec 11, 2025

Summary

  • Add compat package for bidirectional conversion between ModelPack and Docker model-spec formats
  • Implement format detection based on media types
  • Enable interoperability with docker/model-runner

This PR addresses the request from @aftersnow in #151 to help docker-runner become compatible with ModelPack format.

Changes

New Package: compat/docker/v0

  • config.go: Docker model-spec v0.1 type definitions and media type constants
  • convert.go: Bidirectional conversion functions
    • FromModelPack(): Convert ModelPack model to Docker format
    • ToModelPack(): Convert Docker config to ModelPack format

New Package: compat

  • detect.go: Format detection utility (DetectFormat())

Documentation

  • docs/compatibility.md: Usage guide with code examples and field mapping table
  • Updated README.md with compatibility section

Field Mapping

ModelPack Docker Notes
descriptor.createdAt descriptor.createdAt RFC3339 format
config.format config.format Direct mapping
config.paramSize config.gguf.parameter_count Format conversion (e.g., "8b" to "8 B")
config.architecture config.gguf.architecture Direct mapping
config.quantization config.gguf.quantization Direct mapping
modelfs.diffIds files[].diffID Structure conversion

Test plan

  • All existing tests pass (make test)
  • New unit tests for Docker config types
  • New unit tests for conversion functions
  • New unit tests for format detection
  • Build verification (go build ./...)

Related Issues

Add compat package for bidirectional conversion between ModelPack and
Docker model-spec formats. This enables interoperability with
docker/model-runner as requested in issue modelpack#151.

Changes:
- Add compat/docker/v0 package with Docker config types and media types
- Implement FromModelPack() and ToModelPack() conversion functions
- Add compat.DetectFormat() for media type detection
- Add docs/compatibility.md with usage examples
- Update README.md with compatibility section

Closes modelpack#151

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
Copilot AI review requested due to automatic review settings December 11, 2025 23:42
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @thc1006, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the interoperability of ModelPack by introducing a dedicated compatibility layer for Docker model-spec formats. It provides tools for detecting model formats and performing bidirectional conversions, thereby enabling seamless integration with systems like 'docker/model-runner' and addressing a key community request for broader ecosystem compatibility.

Highlights

  • Bidirectional Format Conversion: Introduced a new 'compat' package for seamless bidirectional conversion between ModelPack and Docker model-spec formats.
  • Media Type-Based Format Detection: Added a utility ('compat.DetectFormat') to identify model artifact formats based on their media types.
  • Docker Model-Spec v0.1 Definitions: Implemented Go type definitions and media type constants for Docker model-spec v0.1 within the 'compat/docker/v0' package.
  • Conversion Functions: Provided 'FromModelPack' and 'ToModelPack' functions for converting model configurations between the two formats, including specific field mappings like 'paramSize'.
  • Updated Documentation: Updated 'README.md' and added a comprehensive 'docs/compatibility.md' guide with usage examples, field mapping details, and known limitations.
  • Comprehensive Unit Testing: Included extensive unit tests for the new format detection, Docker config types, and conversion logic to ensure correctness and reliability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a compatibility layer for converting between ModelPack and Docker model-spec formats, which is a great feature for interoperability. The implementation is well-structured with new packages for detection and conversion, accompanied by thorough tests and documentation. I've identified a few areas for improvement, mainly concerning error handling, code clarity, and testing practices. My main concerns are a potential silent error when parsing timestamps and the presence of some unused code. Overall, this is a solid contribution.

Comment on lines +88 to +91
t, err := time.Parse(time.RFC3339, cfg.Descriptor.CreatedAt)
if err == nil {
m.Descriptor.CreatedAt = &t
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

Errors from time.Parse are silently ignored. If CreatedAt has an invalid format, it will be skipped without any indication, which could lead to silent data loss or inconsistencies. It's better to propagate the error to the caller.

		t, err := time.Parse(time.RFC3339, cfg.Descriptor.CreatedAt)
		if err != nil {
			return nil, err
		}
		m.Descriptor.CreatedAt = &t

Comment on lines +21 to +46
func TestDetectFormat(t *testing.T) {
for i, tt := range []struct {
mediaType string
want Format
}{
// ModelPack 格式
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},

// Docker 格式
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},

// 未知格式
{"application/json", FormatUnknown},
{"application/octet-stream", FormatUnknown},
{"", FormatUnknown},
} {
got := DetectFormat(tt.mediaType)
if got != tt.want {
t.Errorf("test %d: DetectFormat(%q) = %v, want %v", i, tt.mediaType, got, tt.want)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This test function can be improved for better maintainability and readability:

  1. Use English comments: The comments are in Chinese, while the rest of the codebase is in English. It's best to maintain consistency for all developers.
  2. Use subtests: For table-driven tests, using t.Run provides clearer output when a test case fails, as it names the specific test that failed. This makes debugging easier.

Here is a suggested refactoring that addresses both points:

func TestDetectFormat(t *testing.T) {
	tests := []struct {
		name      string
		mediaType string
		want      Format
	}{
		// ModelPack formats
		{"ModelPack config", "application/vnd.cncf.model.config.v1+json", FormatModelPack},
		{"ModelPack manifest", "application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
		{"ModelPack weights", "application/vnd.cncf.model.weight.v1.raw", FormatModelPack},

		// Docker formats
		{"Docker config", "application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
		{"Docker GGUF", "application/vnd.docker.ai.gguf.v3", FormatDocker},
		{"Docker license", "application/vnd.docker.ai.license", FormatDocker},

		// Unknown formats
		{"Generic JSON", "application/json", FormatUnknown},
		{"Octet stream", "application/octet-stream", FormatUnknown},
		{"Empty media type", "", FormatUnknown},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := DetectFormat(tt.mediaType)
			if got != tt.want {
				t.Errorf("DetectFormat(%q) = %v, want %v", tt.mediaType, got, tt.want)
			}
		})
	}
}

Comment on lines +52 to +70
if m.Config.ParamSize != "" {
cfg.ModelConfig.GGUF = map[string]any{
"parameter_count": formatParamSizeHuman(m.Config.ParamSize),
}
}

if m.Config.Architecture != "" {
if cfg.ModelConfig.GGUF == nil {
cfg.ModelConfig.GGUF = make(map[string]any)
}
cfg.ModelConfig.GGUF["architecture"] = m.Config.Architecture
}

if m.Config.Quantization != "" {
if cfg.ModelConfig.GGUF == nil {
cfg.ModelConfig.GGUF = make(map[string]any)
}
cfg.ModelConfig.GGUF["quantization"] = m.Config.Quantization
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic for populating the GGUF map involves multiple checks for cfg.ModelConfig.GGUF == nil. This can be simplified by creating the map once, populating it, and then assigning it to cfg.ModelConfig.GGUF only if it contains any fields. This improves readability and reduces redundancy.

Suggested change
if m.Config.ParamSize != "" {
cfg.ModelConfig.GGUF = map[string]any{
"parameter_count": formatParamSizeHuman(m.Config.ParamSize),
}
}
if m.Config.Architecture != "" {
if cfg.ModelConfig.GGUF == nil {
cfg.ModelConfig.GGUF = make(map[string]any)
}
cfg.ModelConfig.GGUF["architecture"] = m.Config.Architecture
}
if m.Config.Quantization != "" {
if cfg.ModelConfig.GGUF == nil {
cfg.ModelConfig.GGUF = make(map[string]any)
}
cfg.ModelConfig.GGUF["quantization"] = m.Config.Quantization
}
gguf := make(map[string]any)
if m.Config.ParamSize != "" {
gguf["parameter_count"] = formatParamSizeHuman(m.Config.ParamSize)
}
if m.Config.Architecture != "" {
gguf["architecture"] = m.Config.Architecture
}
if m.Config.Quantization != "" {
gguf["quantization"] = m.Config.Quantization
}
if len(gguf) > 0 {
cfg.ModelConfig.GGUF = gguf
}

Comment on lines +184 to +244
// parseParamSize parses parameter size string, e.g., "8b" -> 8000000000.
func parseParamSize(s string) int64 {
s = strings.TrimSpace(strings.ToLower(s))
if s == "" {
return 0
}

var numPart string
var unitPart string
for i, c := range s {
if (c >= '0' && c <= '9') || c == '.' {
numPart = s[:i+1]
} else {
unitPart = s[i:]
break
}
}

if numPart == "" {
numPart = s
}

num, err := strconv.ParseFloat(numPart, 64)
if err != nil {
return 0
}

var multiplier int64 = 1
switch strings.ToLower(unitPart) {
case "t":
multiplier = 1_000_000_000_000
case "b":
multiplier = 1_000_000_000
case "m":
multiplier = 1_000_000
case "k":
multiplier = 1_000
}

return int64(num * float64(multiplier))
}

// formatParamSize converts a number to human-readable format, e.g., 8000000000 -> "8b".
func formatParamSize(n int64) string {
if n <= 0 {
return ""
}

switch {
case n >= 1_000_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000_000, 'f', -1, 64) + "t"
case n >= 1_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000, 'f', -1, 64) + "b"
case n >= 1_000_000:
return strconv.FormatFloat(float64(n)/1_000_000, 'f', -1, 64) + "m"
case n >= 1_000:
return strconv.FormatFloat(float64(n)/1_000, 'f', -1, 64) + "k"
default:
return strconv.FormatInt(n, 10)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The functions parseParamSize and formatParamSize are defined and tested, but they are not used within the conversion logic of this package (FromModelPack and ToModelPack use the ...Human variants). Since they are not exported, they appear to be dead code. If they are not intended for future use, they should be removed to keep the codebase clean.

"github.com/opencontainers/go-digest"
)

func TestFromModelPack(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For table-driven tests like this one, consider using subtests with t.Run(tt.name, ...). This provides more descriptive output on test failures by indicating exactly which test case failed, which significantly improves debuggability.

Copy link

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 adds bidirectional conversion support between CNCF ModelPack and Docker model-spec formats, enabling interoperability with docker/model-runner. The implementation includes format detection utilities and comprehensive conversion functions with proper test coverage.

Key Changes:

  • New compat package with format detection based on media type prefixes
  • New compat/docker/v0 package implementing Docker model-spec v0.1 type definitions and conversion logic
  • Comprehensive documentation in docs/compatibility.md with usage examples and field mapping tables

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
compat/detect.go Format detection utility using media type prefix matching
compat/detect_test.go Test cases for format detection covering ModelPack, Docker, and unknown formats
compat/docker/v0/config.go Type definitions for Docker model-spec v0.1 including Config, ModelConfig, and File structs
compat/docker/v0/config_test.go JSON serialization tests ensuring compatibility with Docker model-spec
compat/docker/v0/convert.go Bidirectional conversion functions with parameter size format transformation
compat/docker/v0/convert_test.go Comprehensive conversion tests including edge cases and round-trip validation
docs/compatibility.md Usage guide with code examples, field mapping table, and limitations documentation
README.md Added compatibility section linking to the compatibility guide

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

}

// ToModelPack converts a Docker format config to ModelPack format.
func ToModelPack(cfg Config) (*v1.Model, error) {
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The function signature returns an error, but the function never actually returns an error - it always returns nil. Consider either removing the error return value if errors are not expected, or properly handling and returning errors for invalid inputs such as malformed timestamps in the Descriptor or invalid GGUF field types.

Copilot uses AI. Check for mistakes.
Comment on lines +167 to +244
func parseParamSizeHuman(s string) string {
s = strings.TrimSpace(s)
if s == "" {
return ""
}

parts := strings.Fields(s)
if len(parts) != 2 {
return strings.ToLower(strings.ReplaceAll(s, " ", ""))
}

num := parts[0]
unit := strings.ToLower(parts[1])

return num + unit
}

// parseParamSize parses parameter size string, e.g., "8b" -> 8000000000.
func parseParamSize(s string) int64 {
s = strings.TrimSpace(strings.ToLower(s))
if s == "" {
return 0
}

var numPart string
var unitPart string
for i, c := range s {
if (c >= '0' && c <= '9') || c == '.' {
numPart = s[:i+1]
} else {
unitPart = s[i:]
break
}
}

if numPart == "" {
numPart = s
}

num, err := strconv.ParseFloat(numPart, 64)
if err != nil {
return 0
}

var multiplier int64 = 1
switch strings.ToLower(unitPart) {
case "t":
multiplier = 1_000_000_000_000
case "b":
multiplier = 1_000_000_000
case "m":
multiplier = 1_000_000
case "k":
multiplier = 1_000
}

return int64(num * float64(multiplier))
}

// formatParamSize converts a number to human-readable format, e.g., 8000000000 -> "8b".
func formatParamSize(n int64) string {
if n <= 0 {
return ""
}

switch {
case n >= 1_000_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000_000, 'f', -1, 64) + "t"
case n >= 1_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000, 'f', -1, 64) + "b"
case n >= 1_000_000:
return strconv.FormatFloat(float64(n)/1_000_000, 'f', -1, 64) + "m"
case n >= 1_000:
return strconv.FormatFloat(float64(n)/1_000, 'f', -1, 64) + "k"
default:
return strconv.FormatInt(n, 10)
}
}
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

These helper functions parseParamSize and formatParamSize are defined and tested but never used in the actual conversion code. If they are intended for future use, consider adding a comment explaining this. Otherwise, consider removing them to reduce code maintenance burden.

Suggested change
func parseParamSizeHuman(s string) string {
s = strings.TrimSpace(s)
if s == "" {
return ""
}
parts := strings.Fields(s)
if len(parts) != 2 {
return strings.ToLower(strings.ReplaceAll(s, " ", ""))
}
num := parts[0]
unit := strings.ToLower(parts[1])
return num + unit
}
// parseParamSize parses parameter size string, e.g., "8b" -> 8000000000.
func parseParamSize(s string) int64 {
s = strings.TrimSpace(strings.ToLower(s))
if s == "" {
return 0
}
var numPart string
var unitPart string
for i, c := range s {
if (c >= '0' && c <= '9') || c == '.' {
numPart = s[:i+1]
} else {
unitPart = s[i:]
break
}
}
if numPart == "" {
numPart = s
}
num, err := strconv.ParseFloat(numPart, 64)
if err != nil {
return 0
}
var multiplier int64 = 1
switch strings.ToLower(unitPart) {
case "t":
multiplier = 1_000_000_000_000
case "b":
multiplier = 1_000_000_000
case "m":
multiplier = 1_000_000
case "k":
multiplier = 1_000
}
return int64(num * float64(multiplier))
}
// formatParamSize converts a number to human-readable format, e.g., 8000000000 -> "8b".
func formatParamSize(n int64) string {
if n <= 0 {
return ""
}
switch {
case n >= 1_000_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000_000, 'f', -1, 64) + "t"
case n >= 1_000_000_000:
return strconv.FormatFloat(float64(n)/1_000_000_000, 'f', -1, 64) + "b"
case n >= 1_000_000:
return strconv.FormatFloat(float64(n)/1_000_000, 'f', -1, 64) + "m"
case n >= 1_000:
return strconv.FormatFloat(float64(n)/1_000, 'f', -1, 64) + "k"
default:
return strconv.FormatInt(n, 10)
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +36
// ModelPack 格式
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},

// Docker 格式
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},

// 未知格式
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

Comments are written in Chinese instead of English. The codebase should maintain consistency with English documentation and comments for broader accessibility. Please translate these comments to English.

Suggested change
// ModelPack 格式
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},
// Docker 格式
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},
// 未知格式
// ModelPack format
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},
// Docker format
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},
// Unknown format

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +36
// ModelPack 格式
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},

// Docker 格式
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},

// 未知格式
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

Comments are written in Chinese instead of English. The codebase should maintain consistency with English documentation and comments for broader accessibility. Please translate these comments to English.

Suggested change
// ModelPack 格式
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},
// Docker 格式
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},
// 未知格式
// ModelPack format
{"application/vnd.cncf.model.config.v1+json", FormatModelPack},
{"application/vnd.cncf.model.manifest.v1+json", FormatModelPack},
{"application/vnd.cncf.model.weight.v1.raw", FormatModelPack},
// Docker format
{"application/vnd.docker.ai.model.config.v0.1+json", FormatDocker},
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},
// Unknown format

Copilot uses AI. Check for mistakes.
{"application/vnd.docker.ai.gguf.v3", FormatDocker},
{"application/vnd.docker.ai.license", FormatDocker},

// 未知格式
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

Comments are written in Chinese instead of English. The codebase should maintain consistency with English documentation and comments for broader accessibility. Please translate these comments to English.

Suggested change
// 未知格式
// Unknown format

Copilot uses AI. Check for mistakes.

// FromModelPack converts a ModelPack model to Docker format.
// Note: The Size field cannot be derived from ModelPack and will be set to "0".
func FromModelPack(m v1.Model) (*Config, error) {
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

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

The function signature returns an error, but the function never actually returns an error - it always returns nil. Consider either removing the error return value if errors are not expected, or properly handling and returning errors for invalid inputs such as timestamp parsing failures or invalid format values.

Copilot uses AI. Check for mistakes.
@aftersnow
Copy link
Contributor

aftersnow commented Dec 12, 2025

@thc1006 Great work! Thank you very much for your excellent work. However, these compatibility code sections are more suitable to be in the implementation layer: docker-runner. It might be difficult to merge these modifications into the modelpack/model-spec, as it serves as the specification layer. Thank you again for your contribution, and feel free to discuss this further at any time!

@thc1006
Copy link
Author

thc1006 commented Dec 12, 2025

Dear @aftersnow,

Thank you so much for taking the time to review this PR and for providing such valuable feedback! 🙏

I completely understand and agree with your point — model-spec serves as the specification layer, and compatibility/conversion logic is indeed more appropriate for the implementation layer like https://github.com/docker/model-runner.

Based on your suggestion and the positive response from @ericcurtin in docker/model-spec#3 (where Docker welcomed PRs with backwards compatibility), I plan to:

  1. Open a PR directly to https://github.com/docker/model-runner to propose adding ModelPack format support
  2. Reference this discussion and the original issue for context

I've also addressed all the code review feedback (error handling, unused code removal, comment translations) in my latest commit — hopefully the implementation here can serve as a useful reference for the model-runner integration.

Quick question: Would you prefer me to close this PR now, or keep it open for reference while the docker/model-runner work is in progress?

Thank you again for your guidance and for initiating this important interoperability discussion! Really appreciate your work on both ModelPack and bridging the ecosystem. 😊

Best regards

@aftersnow
Copy link
Contributor

@thc1006 That would be great, thank you! You can keep this PR open while the docker/model-runner work is in progress.

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.

help docker-runner compatible with modelpack

2 participants