Text Classification
Transformers
Safetensors
Laya
x402
agentic-commerce
calibrated-decisions
rlcd
system-one
crypto
base
solana
Instructions to use Priceman614/x402-demand with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Priceman614/x402-demand with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="Priceman614/x402-demand")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Priceman614/x402-demand", device_map="auto") - Laya
How to use Priceman614/x402-demand with Laya:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
|
Download docs/PROCESS.md from Priceman614/x402-demand: direct link, hf CLI and curl.
- Browser
- Download file 11.6 kB
-
https://huggingface.co/Priceman614/x402-demand/resolve/main/docs/PROCESS.md
- Command line
-
hf download hf://Priceman614/x402-demand/docs/PROCESS.md
-
curl -L -o PROCESS.md https://huggingface.co/Priceman614/x402-demand/resolve/main/docs/PROCESS.md
11.6 kB
| # x402 Demand — how the model was built | |
| This is the full record of how the `x402-demand` checkpoints were made: the source | |
| data, the label and why it is shaped that way, the splits, the baselines a checkpoint | |
| had to beat, the training recipe, the results, and what was published. Written so the | |
| run can be repeated, extended, or challenged. | |
| Owner: Ryan Price (Spark Intelligence Station). Started 2026-09-23. | |
| --- | |
| ## 0. Publication policy | |
| | Artifact | Published? | Where | | |
| |---|---|---| | |
| | Checkpoints (weights, tokenizer, config) | **yes** | HF model repo | | |
| | Metrics (`results/*.json`) and figures (`results/*.png`) | **yes** | HF model card | | |
| | Demo app | **yes** | HF Space | | |
| | This document, the training/eval code | on the model repo (as docs), **no public git** | — | | |
| | **The dataset** (snapshots, `data/rows.parquet`, per-row predictions) | **NO** | stays on the Spark box | | |
| The dataset is deliberately withheld. The daily snapshots are the lab's own longitudinal | |
| record of the CDP Bazaar and are the durable asset; the model card describes the data | |
| in aggregate only. `data/` and `runs/` are gitignored so nothing row-level can be | |
| committed by accident. The figures show aggregate rates and scores, never rows. The | |
| demo's example listings are invented, not drawn from the data. | |
| --- | |
| ## 1. Source data | |
| - **What:** the Coinbase CDP x402 discovery index (the "Bazaar"), | |
| `GET https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources`, fetched once | |
| a day, fully paginated (1,000/page), by the lab's `Scout:Bazaar` | |
| (`spark-lab/agents/scouts.py`). Each daily file is `vault/raw/bazaar/YYYY-MM-DD.json`; | |
| this project reads only its `cdp` list. | |
| - **Per listing:** `resource` (URL), `type`, `description`, `price` (USDC atomic units, | |
| 6 decimals), `network`, `lastUpdated`, and `quality` = {`l30DaysTotalCalls`, | |
| `l30DaysUniquePayers`, `lastCalledAt`}. | |
| - **Window used for v1:** 31 snapshots, 2026-08-24 → 2026-09-23. 14.2k-16.2k listings per | |
| day; 26,642 distinct resources seen; 2,464 hosts in the modelled rows. | |
| - **Completeness check:** daily counts are stable (no truncated pages). 1,297 resources | |
| (4.9%) disappear and reappear — "flicker". The label below is built from | |
| `lastCalledAt` timestamps rather than from presence, so it is robust to that. | |
| ### The fact that shaped the label | |
| The index **evicts a listing exactly 30 days after its `quality.lastCalledAt`** (measured | |
| to the second on the lab's own listing on 2026-09-12; `lastUpdated` does not matter). So | |
| "will this listing still be in the index in N days?" is mostly *already decided* by a | |
| timestamp we can read: anything called in the last 30-N days survives by rule. A model | |
| trained on survival would mostly learn that arithmetic. | |
| ## 2. The label | |
| > **`paid_Hd` = 1 iff the listing receives at least one paid call in the H days after the | |
| > anchor snapshot**, i.e. some later snapshot shows `lastCalledAt` ∈ (ref_t, ref_t + H]. | |
| - `ref_t` is the snapshot's reference time = the newest `lastCalledAt` in it (≈ fetch time). | |
| - A listing that is evicted, or stays listed without a new call, is 0. | |
| - H ∈ {7, 14}. A horizon is labelled only if the whole window (+1 day of slack) is observed. | |
| - Result: **330,035 labelled rows** (paid_7d, anchors 0-21), base rate **0.240**; | |
| 241,825 rows for paid_14d (anchors 0-15), base rate **0.324**. | |
| In words: **only a quarter of listed x402 services get paid even once in a week.** | |
| What the label is not: it is not "is this a legitimate service". A self-call to keep a | |
| listing alive counts as a paid call. See §7. | |
| ## 3. Features (all computed from snapshots ≤ t — no look-ahead) | |
| Listing: URL, host, path depth, path parameter present, description (+ length), price in | |
| USD, network. | |
| Telemetry: 30-day calls and unique payers, calls per payer, days since last paid call, | |
| days since listing updated, days observed in the index (with a left-censoring flag for | |
| listings already present on day 0), new-listing flag, presence and payer/call deltas vs 7 | |
| days earlier. | |
| Host aggregates at t: number of listings, share of the host's listings called in the | |
| last 7 days, share with exactly one call per payer, median payers, networks used. | |
| ## 4. Splits — two walls, both enforced in `common.py` | |
| 1. **Host wall.** Hosts are hashed (sha256) into 100 buckets. Buckets 80-99 are **test | |
| hosts**, never seen in training. Many hosts mass-list hundreds of near-identical | |
| endpoints (one lists 840); without this wall a model memorises the host. | |
| 2. **Time wall.** A training row's label window must end before the first test anchor, so | |
| no training label observes the test period. | |
| - paid_7d: train anchors 0-9, validation anchor 10, **test anchors 17-21**. | |
| - paid_14d: train anchor 0, validation anchor 1, **test anchor 15** (31 days only | |
| allows one clean 14-day window; this horizon is secondary until more history exists). | |
| 3. **Calibration hosts.** For the neural models, train-side buckets 70-79 are held out | |
| from training and used for model selection and temperature fitting, so calibration is | |
| measured on hosts the model has not seen. | |
| Test set for paid_7d: 13,644 rows over 442 unseen hosts. | |
| Segments reported everywhere: `all`, `new_listings` (first seen at the anchor: the cold | |
| start), `small_hosts(<=20)` (hosts with ≤ 20 listings: the long tail, less factory noise), | |
| `stale(>7d since call)`. | |
| ## 5. Baselines (`baselines.py`) — what a checkpoint has to beat | |
| | paid_7d, test | all AUC | new listings AUC | small hosts AUC | ECE (all) | | |
| |---|---|---|---|---| | |
| | Recency rule (isotonic on days since last call) | 0.635 | 0.416 | 0.696 | 0.095 | | |
| | Logistic regression, numeric features | **0.678** | 0.500 | 0.731 | **0.052** | | |
| | LightGBM, numeric + network | 0.672 | 0.514 | **0.737** | 0.076 | | |
| Top LightGBM features by gain: 30-day calls, host listing count, host 7-day activity, | |
| days since update, host one-call-per-payer share, price. | |
| Reading: telemetry gets you to AUC ~0.68 on unseen hosts. Brand-new listings are at | |
| chance for every telemetry model: they have no history, and their first "call" is often | |
| the settle that listed them. | |
| ## 6. Neural model (`train_laya.py`) | |
| - **Base:** `convaiinnovations/laya` (ModernBERT-large encoder + decision head, 421M, | |
| Apache-2.0). Output is a Laya checkpoint: it loads with `laya.load()` and answers typed | |
| questions. | |
| - **Questions trained:** two `noul` (yes/no probability) questions, `paid_7d` and | |
| `paid_14d`, with the instructions in `train_laya.py:QUESTIONS`. Use the same wording at | |
| inference. | |
| - **Variants** (only the input state differs): | |
| - `text`: `{resource, description, price_usd, network}`. Works for any listing, | |
| including one not yet listed. The text is identical across a resource's anchors, so | |
| each resource is one item whose **soft target** = the fraction of its training anchors | |
| that were paid. | |
| - `full`: the listing plus telemetry as text (`paid_calls_30d`, `unique_payers_30d`, | |
| `days_since_last_paid_call`, `days_since_listing_updated`, `host_listing_count`, | |
| `host_share_called_in_last_7d`). Two anchors are sampled per resource, with hard targets. | |
| - **Objective:** a single-GPU port of Laya's upstream RLCD recipe. REINFORCE on a strictly | |
| proper scoring rule (log + 0.75 spherical) with a group-mean baseline (G=4, σ 0.4→0.1), | |
| plus a soft cross-entropy term. AdamW with encoder lr 2.5e-5 and head lr 1e-4, weight | |
| decay 0.01, warmup and cosine, micro-batch 16 × accumulation 4, bf16 autocast, gradient | |
| checkpointing, max_len 384 (head budget 192), 3 epochs. The best epoch by held-out | |
| calibration-host AUC is kept. | |
| - **Calibration:** one temperature for `noul`, fitted by LBFGS on the calibration hosts, | |
| written to `rl_agent_config.json` where `laya.Agent` applies it. | |
| - **Hardware:** DGX Spark GB10, ~8.5 GB of GPU memory per run. | |
| ## 7. Results | |
| All numbers are on the held-out test set (future anchors × unseen hosts). Source files: | |
| `runs/laya-*/eval.json`, `runs/bootstrap_full_vs_baselines.json`, published as `results/metrics.json`. | |
| ### paid_7d, ROC AUC | |
| | Model | All (n=13,644) | New listings (n=221) | Small hosts ≤20 (n=6,135) | ECE (all) | | |
| |---|---|---|---|---| | |
| | Recency rule | 0.635 | 0.416 | 0.696 | 0.095 | | |
| | Logistic regression | 0.678 | 0.500 | 0.731 | 0.052 | | |
| | LightGBM | 0.672 | 0.514 | 0.737 | 0.076 | | |
| | **Laya · listing only** (`text`) | 0.639 | **0.575** | 0.668 | 0.116 | | |
| | **Laya · listing + telemetry** (`full`) | **0.732** | 0.581 | **0.754** | 0.110 → **0.079** isotonic | | |
| paid_14d (one test anchor, n=2,631): LightGBM 0.652, `text` 0.653, `full` **0.733**. | |
| ### Significance (paired bootstrap, resampling HOSTS, 1,000 draws) | |
| Rows within a host are strongly correlated, so resampling rows would overstate certainty. | |
| | Comparison | median ΔAUC | 95% CI | P(Δ ≤ 0) | | |
| |---|---|---|---| | |
| | `full` vs LightGBM | +0.058 | [+0.010, +0.110] | 0.014 | | |
| | `full` vs `text` | +0.092 | [+0.051, +0.141] | 0.000 | | |
| | LightGBM + `text` score vs LightGBM, same calibration-host rows | +0.027 | [−0.008, +0.073] | 0.076 | | |
| | … new listings only | +0.080 | [−0.002, +0.153] | 0.026 | | |
| | LightGBM + `full` score vs LightGBM, same rows | +0.017 | [−0.017, +0.068] | 0.202 | | |
| ### Reading | |
| - **`full` is the best single model** and clears the strongest baseline, significant at the | |
| host level. It becomes the paid API. | |
| - **`text` alone is weaker than telemetry**, but it is the only model above chance on | |
| cold-start listings and adds a consistent, not yet conclusive, lift when stacked. It is | |
| the open "shop window" checkpoint. | |
| - **Both Laya models are over-confident above ~0.5.** One temperature cannot fix a | |
| top-end-only miscalibration. The API applies an isotonic map fitted on calibration hosts | |
| (`recalibrate.py` → `isotonic_paid7d.json`): ECE 0.110 → 0.079, Brier 0.180 → 0.164, AUC | |
| unchanged by construction. The open checkpoint ships temperature-only, and its card says so. | |
| - The held-out calibration-host AUC seen during training (0.85 `text`, 0.91 `full`) is much | |
| higher than test. Those rows share training *dates*. Only the time + host wall is honest. | |
| ### Decision (2026-09-23) | |
| | Checkpoint | Release | | |
| |---|---| | |
| | `text` | **public** HF model repo + Space (CPU) | | |
| | `full` + isotonic map | **private** — served as a pay-per-call x402 endpoint from the SentEdge server; weights backed up to a private HF repo | | |
| ## 8. Limitations | |
| - **31 days of history.** One clean 14-day test window, and a single month of seasonality. | |
| - **Paid ≠ legitimate.** Keepalive self-calls and wash traffic count as paid. Roughly 9.8k | |
| listings show ~1 call per payer, a pattern consistent with scripted callers. A "wash" | |
| label needs payer-level data the index does not expose. | |
| - **Index-specific.** Trained on the CDP Bazaar only; other x402 directories may differ. | |
| - **Distribution drift.** The x402 market is weeks old and changing fast; retrain monthly. | |
| ## 9. Reproduce | |
| ```bash | |
| python -m venv .venv && .venv/bin/pip install torch --index-url https://download.pytorch.org/whl/cu130 | |
| .venv/bin/pip install -r requirements.txt | |
| .venv/bin/python build_dataset.py --snap-dir /path/to/bazaar/snapshots # -> data/rows.parquet | |
| .venv/bin/python baselines.py # -> runs/baselines.json | |
| USE_TF=0 .venv/bin/python train_laya.py --variant text --epochs 3 | |
| USE_TF=0 .venv/bin/python train_laya.py --variant full --epochs 3 --anchors-per-resource 2 | |
| USE_TF=0 .venv/bin/python evaluate.py --ckpt runs/laya-text | |
| USE_TF=0 .venv/bin/python evaluate.py --ckpt runs/laya-full | |
| .venv/bin/python make_figures.py # -> results/ | |
| ``` | |