Agent Parser Model-API Serving Troubleshooting
Use this skill when the model-api task exists but serving is still bad.
Failure Buckets
- ALB/TG registration or health
- internal ALB security-group ingress mismatch
- EFS mount/subdirectory/bootstrap
- vLLM sidecar missing or unhealthy
- subnet/AZ-specific outbound path drift
- legacy model selection mismatch
- caller endpoint drift
- vLLM context overflow without successful auto-adjust
Current Contract
- callers should use the internal ALB on port
8001 - common path is
POST /v1/scan model-apishould talk to local sidecarvllm- prefer checking
/readyzfrom inside themodel-apicontainer namespace, not from the EC2 host namespace readyzshould exposequeue_enabled,queue_connected, andqueue_worker_running; record those before blaming caller code
High-Signal Symptoms
- TG has zero targets:
- service not attached to TG
- app/scheduler logs show
Inference API unreachable (all endpoints): All connection attempts failedagainst the internal model-api ALB even though listener/TG are healthy:- internal model-api ALB SG likely does not allow the real app/scheduler task SG on port
8001
- internal model-api ALB SG likely does not allow the real app/scheduler task SG on port
context deadline exceededon mount:- EFS SG/NFS path
No such file or directoryon mount:- missing
/huggingfaceor/adapters
- missing
- one task is healthy but another task on a different subnet has
vllm=UNHEALTHY,model-api=PENDING, and repeatedhuggingface.cotimeouts:- suspect subnet/AZ-specific outbound drift before changing app code
HFValidationErrorafter setting--modelto an absolute path:- the supplied path does not actually exist inside the running container, so vLLM fell back to HF repo-id validation
- 404 on
/v1/models/<legacy>/scan:- legacy selection/routing path still active
- 500 on
/v1/scan:- likely vLLM sidecar or upstream serving issue
- 500 on
/v1/decode/imagewithUnknown argument: show_log:- PaddleOCR runtime/signature drift; remove
show_logfrom init kwargs
- PaddleOCR runtime/signature drift; remove
- 500 on
/v1/decode/imagewithModel name mismatchafter switching to local model dirs:- Paddle 3.2.x needs
text_detection_model_nameandtext_recognition_model_namealongside the local dirs
- Paddle 3.2.x needs
- 500 on
/v1/decode/imagewithpredict() got an unexpected keyword argument clsor similar:- caller is using legacy
.ocr(..., cls=True)path against Paddle 3.x; switch topredict()and parserec_texts
- caller is using legacy
- 500 on
/v1/scanwith vLLM text likeYou passed ... input tokens ... maximum input length ...:- context overflow, not generic app failure
- local
docker exec <model-api> curl http://127.0.0.1:8001/v1/scanis fast but end-to-end scheduler throughput is still much worse thanpgpu:- suspect scheduler ledger/poll/post-processing overhead before changing model-api serving
MODEL_API_QUEUE_ENABLED=falsein the AWS container while local/v1/scantiming is still fine:- note the runtime drift, but do not treat it as the root cause without caller-side timing proof
Current Gotchas
- healthy listener + healthy TG is not enough; the internal ALB SG must explicitly allow the current app/scheduler task SGs on
8001 - if callers hit the ALB but
ConnectErrorpersists, compare:- ALB SG allowed source groups
- actual ECS service task SGs for
agent-parser-appandagent-parser-compliance-scheduler
- current
origin/mainincludes a model-api fix that:- detects vLLM sidecar by backend flavor rather than brittle base URL substring matching
- parses both old and new vLLM context-overflow messages
- retries with a smaller prompt instead of immediately surfacing a 500
- the paired manual re-scan HITL tagging change lives in
app; if the goal is full behavior parity for truncated manual re-scan, deployappas well asmodel-api
EFS Cache Guidance
HF_HOMEis EFS-backed, but--model Qwen/Qwen3.5-9Bstill allows metadata lookups unless offline mode is forced- if one healthy task already populated the cache, prefer:
- keep
--modelas the repo id - set
HF_HUB_OFFLINE=1 - set
TRANSFORMERS_OFFLINE=1 - keep
HF_HOMEon the EFS mount
- keep
- if you must use a local snapshot path, derive the exact path from a healthy running
vllmcontainer instead of transcribing an EFS identifier by hand
Paddle OCR Local-Only Guidance
For attachment image OCR, the proven contract is:
schedulerbootstraps Paddle models into EFS-backedHF_HOMEmodel-apireads only local paths from the manifest and must fail fast if the cache is missing- proven runtime pair is
paddlepaddle==3.0.0withpaddleocr==3.2.0
High-value checks:
- confirm
PADDLE_OCR_MANIFEST_PATHpoints at/efs/huggingface/paddle_ocr_manifest.json - confirm
MODEL_API_PADDLE_REQUIRE_LOCAL_MODELS=true - if
scheduleris expected to bootstrap models, verify the task has actual outbound egress for the first download - after bootstrap, verify
model-apiOCR under--network noneor equivalent no-egress conditions before declaring success - expect the warning
No model hoster is availablein closed networks; do not treat that alone as failure if OCR still succeeds from local cache
When proving the image decode path, use these rules:
- initialize Paddle with both
*_model_nameand*_model_dir - use
predict()as the primary call path - parse
rec_textsfrom the result object - deploy order is
schedulerfirst, thenmodel-api
What To Prove
loadBalancerson ECS service is non-empty- target group target is registered and healthy
- internal ALB listener exists on
8001 - internal ALB SG ingress allows the live app/scheduler task SGs
- model-api logs show runtime/queue start
- vllm logs show actual model serving startup
- if you are on the GPU EC2 host via SSM, use
docker execfor localhost checks becauseawsvpctasks do not share the host loopback - prove whether local
/v1/scanlatency is bad or whether only caller end-to-end latency is bad; those point to different owners - if
/v1/scanreturns 500, capture the first upstream error body before assuming task replacement is needed - if only one task is bad, compare subnet and ENI placement before concluding the task definition is wrong
Output Contract
Return:
- which serving layer is broken
- the first missing proof in the chain
- whether caller redeploy is even relevant yet