docling-project / docling-project/docling
docling model evaluation in s390x
- Dominant language
- Python
- Stars
- 66.4k
- Forks
- 4.8k
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 95
Description
### Question
I am evaluating the Docling model to compare its performance on CPU and NNPA. However, I noticed that when running on the CPU, the model takes around 15–20 minutes just to generate the output. Is this expected behavior for the model?
I have included the notebook with the code below for reference.
```
# Granite Docling Benchmark (Image-only, with token)
# =========================================================
import time
import torch
from transformers import AutoModelForVision2Seq, AutoProcessor
from PIL import Image
from IPython.display import display, HTML
import warnings
warnings.filterwarnings("ignore")
from transformers import logging
logging.set_verbosity_error()
# -------------------------------
# Model and documents setup
# -------------------------------
model_name = "ibm-granite/granite-docling-258M"
documents = [
{
"file_path": "/home/ibm-user/image-2.jpg", # update path if needed
"extra_info": {"doc_id": "img1", "source": "manual"}
}
]
# Must include placeholder
question = "Here is a document: \nQuestion: What is the Net income in 2008?"
devices_to_test = ["cpu", "nnpa"]
results = []
# -------------------------------
# Run inference
# -------------------------------
for device_type in devices_to_test:
try:
if device_type == "nnpa":
import torch_nnpa
device = torch_nnpa.device()
device_label = "NNPA"
else:
device = torch.device("cpu")
device_label = "CPU"
display(HTML(f"
Running on: {device_label}
")) # Load model + processor
start_pipe = time.time()
model = AutoModelForVision2Seq.from_pretrained(
model_name,
trust_remote_code=True
).to(device)
processor = AutoProcessor.from_pretrained(model_name, trust_remote_code=True)
pipeline_loading_time = time.time() - start_pipe
for doc in documents:
file_path = doc["file_path"]
# Load image
img = Image.open(file_path).convert("RGB")
img = img.resize((224, 224))
# Inference
start = time.time()
inputs = processor(
text=[question], # includes
images=[img], # same length as tokens
return_tensors="pt"
).to(device)
#outputs = model.generate(**inputs, max_new_tokens=4, do_sample=False, num_beams=1)
outputs = model.generate(**inputs, max_new_tokens=8)
avg_inference_time = time.time() - start
response = processor.batch_decode(outputs, skip_special_tokens=True)[0]
tokens_generated = len(response.split())
tokens_per_sec = tokens_generated / avg_inference_time if avg_inference_time > 0 else 0
results.append({
"device": device_label,
"doc_id": doc["extra_info"].get("doc_id", ""),
"pipeline_loading_time": pipeline_loading_time,
"inference_time": avg_inference_time,
"tokens_generated": tokens_generated,
"tokens_per_sec": tokens_per_sec,
"response": response
})
except Exception as ex:
print(f" Error on {device_label}: {ex}")
# -------------------------------
# Styled CPU vs NNPA Comparison
# -------------------------------
metrics = ["pipeline_loading_time", "inference_time", "tokens_generated", "tokens_per_sec"]
labels = ["Pipeline Load Time (s)", "Avg Inference Time (s)", "Tokens Generated", "Tokens per second"]
if len(results) > 1:
cpu_result = next((r for r in results if r["device"] == "CPU"), {})
nnpa_result = next((r for r in results if r["device"] == "NNPA"), {})
comparison_html = """
CPU vs NNPA Performance Comparison
"""
row_styles = ["background-color: #ffffff;", "background-color: #f9f9f9;"]
for i, (label, metric) in enumerate(zip(labels, metrics)):
cpu_val_raw = cpu_result.get(metric)
nnpa_val_raw = nnpa_result.get(metric)
cpu_val = f"{cpu_val_raw:.4f}" if isinstance(cpu_val_raw, (int, float)) else "N/A"
nnpa_val = f"{nnpa_val_raw:.4f}" if isinstance(nnpa_val_raw, (int, float)) else "N/A"
improvement_str = "N/A"
improvement_color = "#333"
if isinstance(cpu_val_raw, (int, float)) and isinstance(nnpa_val_raw, (int, float)) and cpu_val_raw > 0 and nnpa_val_raw > 0:
if metric == "inference_time":
speedup = cpu_val_raw / nnpa_val_raw
improvement_str = f"{speedup:.2f}× faster"
improvement_color = "green" if speedup > 1 else "red"
elif metric == "tokens_per_sec":
speedup = nnpa_val_raw / cpu_val_raw
improvement_str = f"{speedup:.2f}× faster"
improvement_color = "green" if speedup > 1 else "red"
else:
improvement = ((nnpa_val_raw - cpu_val_raw) / cpu_val_raw) * 100
improvement_str = f"{improvement:.1f}%"
improvement_color = "green" if improvement > 0 else "red"
row_style = row_styles[i % 2]
comparison_html += f"""
"""
comparison_html += "
Metric
CPU
NNPA
Improvement
{label}
{cpu_val}
{nnpa_val}
{improvement_str}
"
# Add generated responses for clarity
comparison_html += f"""
Generated Answer (NNPA): {nnpa_result.get("response", "N/A")}
"""
display(HTML(comparison_html))
else:
display(HTML("
Not enough results to compare CPU and NNPA.
"))```
Contributor guide
Research direction
Reproduce the inline Granite Docling benchmark on s390x, comparing the CPU and NNPA paths with the stated image and generation settings. Record model-loading and inference times, then determine whether the 15–20 minute CPU runtime is expected and document the comparison outcome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- jupyter-notebook, python, pytorch
- Domain
- machine-learning, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100