Instructions to use echoforest/market-psych-classifier-v1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use echoforest/market-psych-classifier-v1 with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
File size: 3,771 Bytes
3d7c238 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | """Export loading, seeded subsets, steps of similar-length posts and token-budget micro-batches (pure Python).
One optimiser step takes ``posts_per_step`` posts. Steps are drawn from length-sorted pools so their posts have
similar lengths, then shuffled; each step is split into micro-batches whose padded size (rows x longest row)
stays within the token budget. The loss is normalised per step (``step_counts``), so how a step is split into
micro-batches does not change its gradient. No packing: the Gated DeltaNet state does not reset between
packed posts.
"""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import random
def load_jsonl(path) -> list[dict]:
with open(path, encoding='utf-8') as fh:
return [json.loads(line) for line in fh if line.strip()]
def write_jsonl(path, rows) -> None:
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
tmp = path.with_suffix(path.suffix + '.tmp')
with open(tmp, 'w', encoding='utf-8') as fh:
for row in rows:
fh.write(json.dumps(row, ensure_ascii=False, allow_nan=False) + '\n')
tmp.replace(path)
def load_split(data_dir, split: str) -> list[dict]:
return load_jsonl(Path(data_dir) / ('%s.jsonl' % split))
def seeded_order(ids, seed) -> list:
return sorted(ids, key=lambda i: hashlib.sha256(json.dumps([str(seed), i]).encode()).hexdigest())
def subset(rows: list[dict], n: int, seed) -> list[dict]:
"""The first n rows in seeded hash order of their ids (independent of file order); all rows if n >= len."""
if not n or n >= len(rows):
return list(rows)
keep = set(seeded_order([r['id'] for r in rows], seed)[:n])
return [r for r in rows if r['id'] in keep]
def steps(lengths: list[int], posts_per_step: int, seed: int, pool: int = 64) -> list[list[int]]:
"""Shuffled steps of similar-length posts: shuffle, sort within pools of posts_per_step*pool, chunk, shuffle."""
rng = random.Random(seed)
idx = list(range(len(lengths)))
rng.shuffle(idx)
out = []
for s in range(0, len(idx), posts_per_step * pool):
chunk = sorted(idx[s:s + posts_per_step * pool], key=lambda i: (lengths[i], i))
out += [chunk[i:i + posts_per_step] for i in range(0, len(chunk), posts_per_step)]
rng.shuffle(out)
return out
def micro_batches(step: list[int], lengths: list[int], token_budget: int) -> list[list[int]]:
"""Split one step so each micro-batch's padded size (rows x longest) is at most token_budget."""
order = sorted(step, key=lambda i: (-lengths[i], i))
out, current = [], []
for i in order:
width = max([lengths[j] for j in current] + [lengths[i]])
if current and width * (len(current) + 1) > token_budget:
out.append(current)
current = []
current.append(i)
if current:
out.append(current)
return out
def step_counts(labels: list[list[int]]) -> list[int]:
"""Non-null targets per field over one step's label rows (-1 marks a null); at least 1 per field."""
if not labels:
return []
return [max(1, sum(1 for row in labels if row[f] >= 0)) for f in range(len(labels[0]))]
def length_order(lengths: list[int]) -> list[int]:
return sorted(range(len(lengths)), key=lambda i: (lengths[i], i))
def inference_batches(lengths: list[int], token_budget: int) -> list[list[int]]:
"""Length-sorted batches for prediction, each within the padded token budget."""
out, current = [], []
for i in length_order(lengths):
if current and lengths[i] * (len(current) + 1) > token_budget:
out.append(current)
current = []
current.append(i)
if current:
out.append(current)
return out
|