mirror of
https://github.com/docling-project/docling-serve.git
synced 2025-11-29 08:33:50 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b299af002b | ||
|
|
c4c41f16df | ||
|
|
7066f3520a | ||
|
|
6a8190c315 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -444,3 +444,5 @@ pip-selfcheck.json
|
||||
# Makefile
|
||||
.action-lint
|
||||
.markdown-lint
|
||||
|
||||
cookies.txt
|
||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,3 +1,17 @@
|
||||
## [v0.12.0](https://github.com/docling-project/docling-serve/releases/tag/v0.12.0) - 2025-06-03
|
||||
|
||||
### Feature
|
||||
|
||||
* Export annotations in markdown and html (Docling upgrade) ([#202](https://github.com/docling-project/docling-serve/issues/202)) ([`c4c41f1`](https://github.com/docling-project/docling-serve/commit/c4c41f16dff83c5d2a0b8a4c625b5de19b36b7c5))
|
||||
|
||||
### Fix
|
||||
|
||||
* Processing complex params in multipart-form ([#210](https://github.com/docling-project/docling-serve/issues/210)) ([`7066f35`](https://github.com/docling-project/docling-serve/commit/7066f3520a88c07df1c80a0cc6c4339eaac4d6a7))
|
||||
|
||||
### Documentation
|
||||
|
||||
* Add openshift replicasets examples ([#209](https://github.com/docling-project/docling-serve/issues/209)) ([`6a8190c`](https://github.com/docling-project/docling-serve/commit/6a8190c315792bd1e0e2b0af310656baaa5551e5))
|
||||
|
||||
## [v0.11.0](https://github.com/docling-project/docling-serve/releases/tag/v0.11.0) - 2025-05-23
|
||||
|
||||
### Feature
|
||||
|
||||
@@ -359,14 +359,24 @@ class ConvertDocumentsOptions(BaseModel):
|
||||
picture_description_local: Annotated[
|
||||
Optional[PictureDescriptionLocal],
|
||||
Field(
|
||||
description="Options for running a local vision-language model in the picture description. The parameters refer to a model hosted on Hugging Face. This parameter is mutually exclusive with picture_description_api."
|
||||
description="Options for running a local vision-language model in the picture description. The parameters refer to a model hosted on Hugging Face. This parameter is mutually exclusive with picture_description_api.",
|
||||
examples=[
|
||||
PictureDescriptionLocal(repo_id="ibm-granite/granite-vision-3.2-2b"),
|
||||
PictureDescriptionLocal(repo_id="HuggingFaceTB/SmolVLM-256M-Instruct"),
|
||||
],
|
||||
),
|
||||
] = None
|
||||
|
||||
picture_description_api: Annotated[
|
||||
Optional[PictureDescriptionApi],
|
||||
Field(
|
||||
description="API details for using a vision-language model in the picture description. This parameter is mutually exclusive with picture_description_local."
|
||||
description="API details for using a vision-language model in the picture description. This parameter is mutually exclusive with picture_description_local.",
|
||||
examples=[
|
||||
PictureDescriptionApi(
|
||||
url="http://localhost:11434/v1/chat/completions",
|
||||
params={"model": "granite3.2-vision:2b"},
|
||||
)
|
||||
],
|
||||
),
|
||||
] = None
|
||||
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
import inspect
|
||||
import json
|
||||
import re
|
||||
from typing import Union
|
||||
from typing import Union, get_args, get_origin
|
||||
|
||||
from fastapi import Depends, Form
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, TypeAdapter
|
||||
|
||||
|
||||
def is_pydantic_model(type_):
|
||||
try:
|
||||
if inspect.isclass(type_) and issubclass(type_, BaseModel):
|
||||
return True
|
||||
|
||||
origin = get_origin(type_)
|
||||
if origin is Union:
|
||||
args = get_args(type_)
|
||||
return any(
|
||||
inspect.isclass(arg) and issubclass(arg, BaseModel)
|
||||
for arg in args
|
||||
if arg is not type(None)
|
||||
)
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
# Adapted from
|
||||
@@ -12,25 +33,62 @@ def FormDepends(cls: type[BaseModel]):
|
||||
new_parameters = []
|
||||
|
||||
for field_name, model_field in cls.model_fields.items():
|
||||
annotation = model_field.annotation
|
||||
description = model_field.description
|
||||
default = (
|
||||
Form(..., description=description)
|
||||
if model_field.is_required()
|
||||
else Form(
|
||||
model_field.default,
|
||||
examples=model_field.examples,
|
||||
description=description,
|
||||
)
|
||||
)
|
||||
|
||||
# Flatten nested Pydantic models by accepting them as JSON strings
|
||||
if is_pydantic_model(annotation):
|
||||
annotation = str
|
||||
default = Form(
|
||||
None
|
||||
if model_field.default is None
|
||||
else json.dumps(model_field.default.model_dump(mode="json")),
|
||||
description=description,
|
||||
examples=None
|
||||
if not model_field.examples
|
||||
else [
|
||||
json.dumps(ex.model_dump(mode="json"))
|
||||
for ex in model_field.examples
|
||||
],
|
||||
)
|
||||
|
||||
new_parameters.append(
|
||||
inspect.Parameter(
|
||||
name=field_name,
|
||||
kind=inspect.Parameter.POSITIONAL_ONLY,
|
||||
default=(
|
||||
Form(...)
|
||||
if model_field.is_required()
|
||||
else Form(model_field.default)
|
||||
),
|
||||
annotation=model_field.annotation,
|
||||
default=default,
|
||||
annotation=annotation,
|
||||
)
|
||||
)
|
||||
|
||||
async def as_form_func(**data):
|
||||
for field_name, model_field in cls.model_fields.items():
|
||||
value = data.get(field_name)
|
||||
annotation = model_field.annotation
|
||||
|
||||
# Parse nested models from JSON string
|
||||
if value is not None and is_pydantic_model(annotation):
|
||||
try:
|
||||
validator = TypeAdapter(annotation)
|
||||
data[field_name] = validator.validate_json(value)
|
||||
except Exception as e:
|
||||
raise ValueError(f"Invalid JSON for field '{field_name}': {e}")
|
||||
|
||||
return cls(**data)
|
||||
|
||||
sig = inspect.signature(as_form_func)
|
||||
sig = sig.replace(parameters=new_parameters)
|
||||
as_form_func.__signature__ = sig # type: ignore
|
||||
|
||||
return Depends(as_form_func)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# This example deployment configures Docling Serve with a Route + Sticky sessions, a Service and cpu image
|
||||
---
|
||||
kind: Route
|
||||
apiVersion: route.openshift.io/v1
|
||||
metadata:
|
||||
name: docling-serve
|
||||
labels:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
annotations:
|
||||
haproxy.router.openshift.io/disable_cookies: "false" # this annotation enables the sticky sessions
|
||||
spec:
|
||||
path: /
|
||||
to:
|
||||
kind: Service
|
||||
name: docling-serve
|
||||
port:
|
||||
targetPort: http
|
||||
tls:
|
||||
termination: edge
|
||||
insecureEdgeTerminationPolicy: Redirect
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: docling-serve
|
||||
labels:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 5001
|
||||
targetPort: http
|
||||
selector:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: docling-serve
|
||||
labels:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: docling-serve
|
||||
component: docling-serve-api
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
containers:
|
||||
- name: api
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 1Gi
|
||||
env:
|
||||
- name: DOCLING_SERVE_ENABLE_UI
|
||||
value: 'true'
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 5001
|
||||
protocol: TCP
|
||||
imagePullPolicy: Always
|
||||
image: 'ghcr.io/docling-project/docling-serve'
|
||||
@@ -192,3 +192,45 @@ curl -X 'POST' \
|
||||
"http_sources": [{"url": "https://arxiv.org/pdf/2501.17887"}]
|
||||
}'
|
||||
```
|
||||
|
||||
### ReplicaSets with `sticky sessions`
|
||||
|
||||
Manifest example: [docling-serve-replicas-w-sticky-sessions.yaml](./deploy-examples/docling-serve-replicas-w-sticky-sessions.yaml)
|
||||
|
||||
This deployment has the following features:
|
||||
|
||||
- Deployment configuration with 3 replicas
|
||||
- Service configuration
|
||||
- Expose the service using a OpenShift `Route` and enables sticky sessions
|
||||
|
||||
Install the app with:
|
||||
|
||||
```sh
|
||||
oc apply -f docs/deploy-examples/docling-serve-replicas-w-sticky-sessions.yaml
|
||||
```
|
||||
|
||||
For using the API:
|
||||
|
||||
```sh
|
||||
# Retrieve the endpoint
|
||||
DOCLING_NAME=docling-serve
|
||||
DOCLING_ROUTE="https://$(oc get routes $DOCLING_NAME --template={{.spec.host}})"
|
||||
|
||||
# Make a test query, store the cookie and taskid
|
||||
task_id=$(curl -s -X 'POST' \
|
||||
"${DOCLING_ROUTE}/v1alpha/convert/source/async" \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"http_sources": [{"url": "https://arxiv.org/pdf/2501.17887"}]
|
||||
}' \
|
||||
-c cookies.txt | grep -oP '"task_id":"\K[^"]+')
|
||||
```
|
||||
|
||||
```sh
|
||||
# Grab the taskid and cookie to check the task status
|
||||
curl -v -X 'GET' \
|
||||
"${DOCLING_ROUTE}/v1alpha/status/poll/$task_id?wait=0" \
|
||||
-H "accept: application/json" \
|
||||
-b "cookies.txt"
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "docling-serve"
|
||||
version = "0.11.0" # DO NOT EDIT, updated automatically
|
||||
version = "0.12.0" # DO NOT EDIT, updated automatically
|
||||
description = "Running Docling as a service"
|
||||
license = {text = "MIT"}
|
||||
authors = [
|
||||
@@ -31,6 +31,7 @@ classifiers = [
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"docling[vlm]~=2.28",
|
||||
"docling-core>=2.32.0",
|
||||
"mlx-vlm~=0.1.12; sys_platform == 'darwin' and platform_machine == 'arm64'",
|
||||
"fastapi[standard]~=0.115",
|
||||
"httpx~=0.28",
|
||||
|
||||
77
tests/test_file_opts.py
Normal file
77
tests/test_file_opts.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from asgi_lifespan import LifespanManager
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
|
||||
from docling_core.types import DoclingDocument
|
||||
from docling_core.types.doc.document import PictureDescriptionData
|
||||
|
||||
from docling_serve.app import create_app
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def event_loop():
|
||||
return asyncio.get_event_loop()
|
||||
|
||||
|
||||
@pytest_asyncio.fixture(scope="session")
|
||||
async def app():
|
||||
app = create_app()
|
||||
|
||||
async with LifespanManager(app) as manager:
|
||||
print("Launching lifespan of app.")
|
||||
yield manager.app
|
||||
|
||||
|
||||
@pytest_asyncio.fixture(scope="session")
|
||||
async def client(app):
|
||||
async with AsyncClient(
|
||||
transport=ASGITransport(app=app), base_url="http://app.io"
|
||||
) as client:
|
||||
print("Client is ready")
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_convert_file(client: AsyncClient):
|
||||
"""Test convert single file to all outputs"""
|
||||
|
||||
endpoint = "/v1alpha/convert/file"
|
||||
options = {
|
||||
"to_formats": ["md", "json"],
|
||||
"image_export_mode": "placeholder",
|
||||
"ocr": False,
|
||||
"do_picture_description": True,
|
||||
"picture_description_api": json.dumps(
|
||||
{
|
||||
"url": "http://localhost:11434/v1/chat/completions", # ollama
|
||||
"params": {"model": "granite3.2-vision:2b"},
|
||||
"timeout": 60,
|
||||
"prompt": "Describe this image in a few sentences. ",
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
current_dir = os.path.dirname(__file__)
|
||||
file_path = os.path.join(current_dir, "2206.01062v1.pdf")
|
||||
|
||||
files = {
|
||||
"files": ("2206.01062v1.pdf", open(file_path, "rb"), "application/pdf"),
|
||||
}
|
||||
|
||||
response = await client.post(endpoint, files=files, data=options)
|
||||
assert response.status_code == 200, "Response should be 200 OK"
|
||||
|
||||
data = response.json()
|
||||
|
||||
doc = DoclingDocument.model_validate(data["document"]["json_content"])
|
||||
|
||||
for pic in doc.pictures:
|
||||
for ann in pic.annotations:
|
||||
if isinstance(ann, PictureDescriptionData):
|
||||
print(f"{pic.self_ref}")
|
||||
print(ann.text)
|
||||
17
uv.lock
generated
17
uv.lock
generated
@@ -568,7 +568,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "docling"
|
||||
version = "2.33.0"
|
||||
version = "2.34.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "beautifulsoup4", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
@@ -598,9 +598,9 @@ dependencies = [
|
||||
{ name = "tqdm", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "typer", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/36/d8/76740f7d40a28794365e76029e7379f7d1b5994e24aaac899c3bb280e426/docling-2.33.0.tar.gz", hash = "sha256:40c27df6a7f90b8fb4279a4094ac26c48f3dbd38ceda0d3208e6d63eda2e8660", size = 132120, upload-time = "2025-05-20T19:56:06.46Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9c/42/33334eeaa3d42a4b3406adc7bbef8c655d026c1c41ad0a8fa858bbb7ef1b/docling-2.34.0.tar.gz", hash = "sha256:52ad3c79b7e56e978fcdd8f2040fe739584e25e1c2fd5f9519fe3d51002de0d2", size = 135016, upload-time = "2025-05-22T18:45:59.786Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/23/6dddf454610c4dff5799f9becbbc752b8595169de57c02a1d39067f5f2b5/docling-2.33.0-py3-none-any.whl", hash = "sha256:6c0ee223c5da551adc5da15aae205aaebf78222780198cb5a21c85648da618ba", size = 169441, upload-time = "2025-05-20T19:56:04.806Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/b6/b855f19ab37a6f92b60a31a7db57160048f88a980aef4b97a5c260860ed4/docling-2.34.0-py3-none-any.whl", hash = "sha256:a69c368382cc824a5a5ad21882b8772f85117a25c81257a57d54582bf38b2810", size = 173153, upload-time = "2025-05-22T18:45:58.295Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -611,7 +611,7 @@ vlm = [
|
||||
|
||||
[[package]]
|
||||
name = "docling-core"
|
||||
version = "2.31.2"
|
||||
version = "2.32.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "jsonref", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
@@ -625,9 +625,9 @@ dependencies = [
|
||||
{ name = "typer", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/6c/8263ec8b44f96a42fff0856ea1c1b7471dba377f18274049e2235f979be7/docling_core-2.31.2.tar.gz", hash = "sha256:6d61863ce492affc45aa522c291631db0be7c50dc146cb93c42af7ff00bd22a2", size = 113011, upload-time = "2025-05-22T15:28:41.731Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3b/53/6017e92236172a994d8592db285990cd911dbbd328fab022406efc66e605/docling_core-2.32.0.tar.gz", hash = "sha256:3ec21461f309540bd8bf4880f6c2f0144f6895988102a4204ca5549c76a945c8", size = 113939, upload-time = "2025-05-27T13:45:19.861Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/75/8ff897047e9be98484fd3b2ce87021434bb3da2dc93ab47854ddcab5da31/docling_core-2.31.2-py3-none-any.whl", hash = "sha256:a6db62ac49febcc9e3e24a9acf58e88342ad7f76ab03217b6a3365509eb12eda", size = 142921, upload-time = "2025-05-22T15:28:40.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/29/eac2c6af02e21090fab38a1fcb2471baf59b346af4d35312cdb6ec68595a/docling_core-2.32.0-py3-none-any.whl", hash = "sha256:6c643b45a18c5ed8cecf12d1eeeb7ff677dcfdb24fa4aa88122e3c9cc2aeb58d", size = 143730, upload-time = "2025-05-27T13:45:18.061Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -703,10 +703,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "docling-serve"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "docling", extra = ["vlm"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "docling-core", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "fastapi", extra = ["standard"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "httpx", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
{ name = "kfp", extra = ["kubernetes"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-cu124') or (extra == 'extra-13-docling-serve-cpu' and extra == 'extra-13-docling-serve-flash-attn')" },
|
||||
@@ -760,6 +761,7 @@ dev = [
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "docling", extras = ["vlm"], specifier = "~=2.28" },
|
||||
{ name = "docling-core", specifier = ">=2.32.0" },
|
||||
{ name = "fastapi", extras = ["standard"], specifier = "~=0.115" },
|
||||
{ name = "flash-attn", marker = "platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'flash-attn'", specifier = "~=2.7.0" },
|
||||
{ name = "gradio", marker = "extra == 'ui'", specifier = "~=5.9" },
|
||||
@@ -4785,7 +4787,6 @@ wheels = [
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a845b6f3bda3c40f736847dede95d8bfec81fb7e11458cd25973ba13542cf1f6" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:64123c05615e27368c7a7816f6e39c6d219998693beabde0b0b9cedf91b5ed8b" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp312-cp312-win_amd64.whl", hash = "sha256:69e25c973bdd7ea24b0fa9f9792114950afaeb8f819e5723819b923f50989175" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp312-cp312-win_arm64.whl", hash = "sha256:1d7a6f33868276770a657beec7f77c7726b4da9d0739eff1b3ae64cc9a09d8e3" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:addf9107939522ffb3b60d2900fee838a77dbe098e2643e01164f46f8612f9c0" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3b09aa2c8d30fa567a8d13270fbf9af7ee472fdfafbc7dfdc87c607bf46001f7" },
|
||||
{ url = "https://download.pytorch.org/whl/cpu/torch-2.7.0%2Bcpu-cp313-cp313-win_amd64.whl", hash = "sha256:99ca8f4cb53484c45bb668657069c17139c07367ea20ddef2c0ce8412f42da2f" },
|
||||
|
||||
Reference in New Issue
Block a user