Text Generation
PEFT
Safetensors
English
granite
lora
meetings
action-items
decisions
information-extraction
local-inference
conversational
Instructions to use Privoid-ai/Privoid-Action-1B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use Privoid-ai/Privoid-Action-1B with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("ibm-granite/granite-4.0-1b") model = PeftModel.from_pretrained(base_model, "Privoid-ai/Privoid-Action-1B") - Notebooks
- Google Colab
- Kaggle
Privoid Action-1B experimental preview (LoRA adapter, validator, API, locked test results)
b68d688 verified |
Download docs/API.md from Privoid-ai/Privoid-Action-1B: direct link, hf CLI and curl.
- Browser
- Download file 7.13 kB
-
https://huggingface.co/Privoid-ai/Privoid-Action-1B/resolve/main/docs/API.md
- Command line
-
hf download hf://Privoid-ai/Privoid-Action-1B/docs/API.md
-
curl -L -o API.md https://huggingface.co/Privoid-ai/Privoid-Action-1B/resolve/main/docs/API.md
7.13 kB
| # Privoid Action — local inference API | |
| A minimal FastAPI service (`privoid_action_api/`) that serves the Action adapter on the original Granite base, or a | |
| validated merged model, from **local files only**. | |
| ## Run | |
| ```powershell | |
| cd Privoid-Action-1B | |
| copy api\config.example.json api\config.json # then set adapter_path to this repository's root folder | |
| python -m privoid_action_api --config api\config.json --check-config | |
| python -m privoid_action_api --config api\config.json | |
| ``` | |
| * Binds to `127.0.0.1:8095` by default. Any non-loopback host is refused unless `allow_non_loopback: true` is set. | |
| * Startup sets `HF_HUB_OFFLINE=1` / `TRANSFORMERS_OFFLINE=1` before any Hugging Face import and loads with | |
| `local_files_only=True`. It never downloads, trains or prepares data. If artifacts are missing or invalid, the server | |
| still starts, `/health` reports `model_state: "unavailable"`, and `/extract` returns 503. | |
| * The loader refuses adapters whose base is not Granite 4.0 1B. | |
| * The model loads at startup (`load_on_startup: true`). One generation runs at a time (`max_concurrent: 1`, sized for | |
| a 12 GB GPU), with up to `max_queue` requests waiting. | |
| ## Endpoints | |
| ### `GET /health` | |
| Process health. Never loads or downloads anything. | |
| ```json | |
| {"status": "ok", "model_state": "ready", "request_id": "3f1c0a9e5b7d2c41"} | |
| ``` | |
| `model_state` is one of `not_loaded`, `loading`, `ready`, `unavailable`. | |
| ### `GET /model-info` | |
| Model identity (base ID and revision, adapter folder name and a short weight hash), schema version, and limits | |
| (`max_prompt_tokens`, `max_new_tokens`, `max_body_bytes`, timeout, concurrency, contract limits). Filesystem paths are | |
| not exposed. | |
| ### `POST /extract` | |
| Body: one transcript segment in the input schema (`docs/SCHEMA.md` §1). Example requests are in `examples/`: | |
| ```powershell | |
| curl.exe -s -X POST http://127.0.0.1:8095/extract -H "content-type: application/json" ` | |
| --data-binary "@examples/request_accepted_request.json" | |
| ``` | |
| Response 200 (abridged; the full illustrative response is in `examples/response_accepted_request.json`. It was produced | |
| by the deterministic finalizer from a hand-written output, **not** by the model): | |
| ```json | |
| { | |
| "request_id": "…", "schema_version": "1.0", | |
| "result": { | |
| "schema_version": "1.0", "meeting_id": "meeting-001", | |
| "actions": [{ | |
| "id": "A1", "task": "Send the revised proposal.", "owner_speaker_ids": ["S2"], "owner_text": "Omar", | |
| "assignment_status": "accepted", "deadline_text": "Friday", "conditions": [], "status": "active", | |
| "evidence": [{"turn_id": "T1", "quote": "Omar, can you send the revised proposal by Friday?"}, | |
| {"turn_id": "T2", "quote": "Yes, I will send it by Friday."}], | |
| "needs_review": false, "review_reasons": [], "pipeline_flags": ["deadline_not_normalized"], | |
| "owner_names": ["Omar"], "deadline_normalized": null, | |
| "deadline_normalization": {"rule": null, "reason": "bare_weekday_ambiguous"}}], | |
| "decisions": [], "unresolved_requests": [], "rejected_records": []}, | |
| "validation": {"raw_output_fully_valid": true, "rejected_record_count": 0, "grounded_record_count": 0}, | |
| "usage": {"prompt_tokens": 882, "seconds": 1.9}, | |
| "model": {"backend": "transformers", "base_model_id": "ibm-granite/granite-4.0-1b", "…": "…"}, | |
| "notice": "Records are extracted from the transcript for human review. They do not create tasks, …" | |
| } | |
| ``` | |
| (The `seconds` value above is a placeholder, not a measurement.) | |
| ### `POST /extract-meeting` (experimental, disabled by default) | |
| Enable with `enable_meeting_endpoint: true`. The endpoint cuts the meeting into whole-turn segments | |
| (`max_segment_tokens`, `segment_overlap_turns`), extracts each segment, and reconciles the results with the documented | |
| rules (`docs/SCHEMA.md` §5). The response is marked `"experimental": true` and includes `segments`, | |
| `reconciliation_log`, `limitations`, `segment_failures` and `complete`. Its quality is measured separately (notebook | |
| §10.5). Cross-segment cancellations are flagged, not applied. | |
| ## Errors | |
| All errors are JSON: `{"error": code, "message": text, "request_id": id, …}`. They never contain stack traces or | |
| filesystem paths. | |
| | Status | `error` | When | | |
| |---|---|---| | |
| | 400 | `invalid_json` | Body is not JSON | | |
| | 413 | `input_too_large` | Body > `max_body_bytes`, a contract size limit, or prompt tokens > `max_prompt_tokens`. **Nothing is truncated**; split the transcript. | | |
| | 422 | `invalid_input` | Schema problems (unknown speaker, duplicate turn ID, invalid date or timezone, control sequences …), listed in `problems` | | |
| | 429 | `busy` | All slots busy and the wait queue is full | | |
| | 502 | `model_output_invalid` | The model output was not one schema-valid JSON object. No records are returned and none are invented. | | |
| | 503 | `model_unavailable` | Model not loaded (see the server log) | | |
| | 504 | `timeout` | Generation exceeded `request_timeout_s`. Generation is also bounded by `max_new_tokens` and a matching `max_time`, and the slot stays occupied until the worker thread really finishes. | | |
| | 500 | `internal_error` | Unexpected failure (details only in the server log, keyed by request ID) | | |
| A record that fails validation (quote not found, unknown speaker, inconsistent status) is returned in | |
| `result.rejected_records` with its errors, and `validation.raw_output_fully_valid` is `false`. Valid records are still | |
| returned. | |
| With `ground_evidence: true` (the default), quotes that the model tidied (fillers or repeated words dropped) or | |
| attached to a neighbouring turn are first re-anchored to the transcript's verbatim words; see `docs/SCHEMA.md` §2.5. | |
| Every record changed this way carries a pipeline flag, and `validation.grounded_record_count` counts them. Set | |
| `ground_evidence: false` to reject such records instead. | |
| ## Privacy behaviour | |
| * Transcript bodies are never logged and never written to disk. Log lines carry the request ID, path, status, latency, | |
| turn count, prompt-token count and validation counts only. Uvicorn's access log is disabled. | |
| * No cloud fallback exists. The only network listener is the configured local address. | |
| * Validation, and any constrained decoding a client might add, ensures the output is well-formed. It is **not proof of | |
| semantic correctness**: owners, statuses and deadlines must still be reviewed by a human before anyone acts on them. | |
| * Extracted records never send messages, create tasks in external systems, or commit participants to anything. | |
| Privacy of a deployment also depends on the surrounding application, its logs and storage, the host OS and its | |
| telemetry, and the network configuration. Those are outside this API. | |
| ## Tests | |
| `python -m unittest discover -s tests -t .` runs the API tests against a **mocked** backend. They cover every route, | |
| error code, oversize rejection, invalid-output rejection, record-level rejection, timeouts, the concurrency bound, a full | |
| queue (429), hidden internal errors, the loopback-only default, no transcript text in logs, and a check that importing | |
| the API does not import torch/transformers/peft/trl. Real-model checks are in notebook §12 (`ALLOW_API_CHECKS`). | |