Text Generation
PEFT
Safetensors
lora
trl
grpo
gdpo
dpo
divpo
rlhf
diversity
creative-writing
mode-collapse
Instructions to use Mercity/creative-writing-llm with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use Mercity/creative-writing-llm with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
| """ | |
| Diversity math over an embedding group. Pure numpy, no torch. | |
| Given L2-normalized embeddings E = [e_1..e_G] (shape G x d) for ONE prompt's | |
| generation group, we expose two families of per-sample diversity credit: | |
| 1. deviation d_i = mean_{j!=i} (1 - cos(e_i, e_j)) | |
| -- pairwise, cheap, but blind to cluster structure: | |
| two tight far-apart clusters score as high as a spread. | |
| 2. marginal m_i = logdet(L) - logdet(L_{-i}) | |
| contribution -- leave-one-out volume credit under the cosine kernel. | |
| A duplicate contributes ~nothing (its direction is already | |
| spanned), so this DOES see cluster structure. | |
| Both are per-sample. This is deliberate: a set-level scalar (e.g. logdet(L) | |
| itself) is constant within a GRPO group, so its within-group std is 0 and the | |
| normalized advantage is identically 0. It cannot train anything. Every | |
| quantity here varies across i within a group. | |
| """ | |
| from __future__ import annotations | |
| import numpy as np | |
| EPS_JITTER = 1e-3 | |
| def l2_normalize(E: np.ndarray, axis: int = -1) -> np.ndarray: | |
| """Row-normalize; zero rows are left as zeros rather than NaN.""" | |
| E = np.asarray(E, dtype=np.float64) | |
| n = np.linalg.norm(E, axis=axis, keepdims=True) | |
| return E / np.maximum(n, 1e-12) | |
| def cosine_kernel(E: np.ndarray, eps: float = EPS_JITTER) -> np.ndarray: | |
| """L = E E^T + eps*I. | |
| E must be L2-normalized, so diag(E E^T) = 1 and L is a correlation-like | |
| PSD matrix. The eps jitter keeps logdet finite when rows are collinear | |
| (exact duplicates make E E^T singular). | |
| """ | |
| E = np.asarray(E, dtype=np.float64) | |
| L = E @ E.T | |
| L = 0.5 * (L + L.T) # kill float asymmetry before Cholesky | |
| return L + eps * np.eye(L.shape[0], dtype=np.float64) | |
| def pairwise_deviation(E: np.ndarray) -> np.ndarray: | |
| """d_i = mean_{j != i} (1 - cos(e_i, e_j)). Shape (G,). | |
| G == 1 has no off-diagonal terms; we return 0.0 (a lone sample has no | |
| measurable deviation, and 0 is the neutral value for the reward). | |
| """ | |
| E = np.asarray(E, dtype=np.float64) | |
| G = E.shape[0] | |
| if G < 2: | |
| return np.zeros(G, dtype=np.float64) | |
| S = E @ E.T | |
| D = 1.0 - S | |
| np.fill_diagonal(D, 0.0) | |
| return D.sum(axis=1) / (G - 1) | |
| def _logdet_psd(L: np.ndarray) -> float: | |
| """logdet via Cholesky; falls back to slogdet if L drifts non-PD.""" | |
| try: | |
| c = np.linalg.cholesky(L) | |
| return float(2.0 * np.sum(np.log(np.diag(c)))) | |
| except np.linalg.LinAlgError: | |
| sign, ld = np.linalg.slogdet(L) | |
| if sign <= 0: | |
| return float("-inf") | |
| return float(ld) | |
| def logdet_volume(E: np.ndarray, eps: float = EPS_JITTER) -> float: | |
| """D(Y) = logdet(E E^T + eps I). Set-level scalar. | |
| Report this as a METRIC. Never hand it to GRPO as a per-sample reward: | |
| it is identical for every i in the group -> zero advantage. | |
| """ | |
| if np.asarray(E).shape[0] == 0: | |
| return 0.0 | |
| return _logdet_psd(cosine_kernel(E, eps)) | |
| def marginal_contributions(E: np.ndarray, eps: float = EPS_JITTER) -> np.ndarray: | |
| """m_i = logdet(L) - logdet(L_{-i}), shape (G,). | |
| Computed by G explicit leave-one-out logdets. G <= 16 here, so this is | |
| ~16 Cholesky calls on a 15x15 matrix -- utterly negligible next to a | |
| single LLM forward pass. Rank-one downdate machinery would be a | |
| micro-optimization with real numerical-stability downside; not worth it. | |
| Interpretation: m_i is the log-volume the group loses by dropping i. | |
| A duplicate has m_i ~ log(eps) -> large negative. An orthogonal direction | |
| has m_i ~ log(1+eps) ~ 0. So m_i is a *penalty scale*: higher (closer to | |
| 0) means "this sample carries a direction nothing else covers". | |
| """ | |
| E = np.asarray(E, dtype=np.float64) | |
| G = E.shape[0] | |
| if G < 2: | |
| return np.zeros(G, dtype=np.float64) | |
| L = cosine_kernel(E, eps) | |
| full = _logdet_psd(L) | |
| out = np.empty(G, dtype=np.float64) | |
| idx = np.arange(G) | |
| for i in range(G): | |
| keep = idx[idx != i] | |
| out[i] = full - _logdet_psd(L[np.ix_(keep, keep)]) | |
| return out | |
| def effective_rank(E: np.ndarray, eps: float = 1e-12) -> float: | |
| """exp(Shannon entropy of the normalized Gram spectrum). Roy & Vetterli. | |
| Reads as "how many distinct directions does this set effectively span": | |
| 1.0 for identical stories, G for mutually orthogonal ones, ~2 for two tight | |
| clusters. Reported as a METRIC, never used as a reward (it is set-level, so | |
| it is constant within a group and would produce zero advantage). | |
| This exists because silhouette-selected k-means turned out to be unusable as | |
| a mode counter on this data: a fully collapsed set and a fully spread set | |
| both peak near silhouette 0.20 (at k=4 and k=7 respectively), because | |
| k-means partitions isotropic data happily regardless of spread. Effective | |
| rank has no k to select and degrades gracefully. | |
| """ | |
| E = np.asarray(E, dtype=np.float64) | |
| if E.shape[0] == 0: | |
| return 0.0 | |
| if E.shape[0] == 1: | |
| return 1.0 | |
| L = E @ E.T | |
| w = np.linalg.eigvalsh(0.5 * (L + L.T)) | |
| w = np.clip(w, 0.0, None) | |
| s = w.sum() | |
| if s <= 0: | |
| return 1.0 | |
| p = w / s | |
| p = p[p > eps] | |
| return float(np.exp(-(p * np.log(p)).sum())) | |
| def zscore(x: np.ndarray, ddof: int = 0) -> np.ndarray: | |
| """Per-group z-score. Constant input -> all zeros (not NaN). | |
| Used on m_i before it enters the reward: raw m_i lives on a log scale | |
| with a long negative tail (a duplicate pair can hit log(1e-3) ~ -6.9), | |
| which would otherwise dominate the quality term. | |
| """ | |
| x = np.asarray(x, dtype=np.float64) | |
| if x.size == 0: | |
| return x | |
| s = x.std(ddof=ddof) | |
| if not np.isfinite(s) or s < 1e-12: | |
| return np.zeros_like(x) | |
| return (x - x.mean()) / s | |
| def scale_to_reference(x: np.ndarray, ref_scale: float = 1.0) -> np.ndarray: | |
| """Rescale x to have unit-ish spread times ref_scale, preserving mean 0. | |
| Deviation d_i lives in [0, 2] but in practice clusters in [0.1, 0.5] for | |
| same-prompt stories -- an order of magnitude below judge quality (0-10). | |
| Feeding raw d_i with alpha=0.5 would make the diversity term invisible. | |
| """ | |
| return zscore(x) * float(ref_scale) | |
| def greedy_diverse_subset( | |
| quality: np.ndarray, | |
| E: np.ndarray, | |
| k: int, | |
| lam: float = 1.0, | |
| eps: float = EPS_JITTER, | |
| ) -> list[int]: | |
| """Greedily pick k indices maximizing sum(quality) + lam * logdet(L_S). | |
| Standard submodular greedy: the objective is monotone-ish and DPP logdet | |
| is submodular, so greedy carries the usual (1 - 1/e) flavor of guarantee. | |
| Used to build E3's multi-positive chosen sets. | |
| Returns indices into the rows of E, in selection order. | |
| """ | |
| quality = np.asarray(quality, dtype=np.float64) | |
| E = np.asarray(E, dtype=np.float64) | |
| G = E.shape[0] | |
| k = int(min(k, G)) | |
| if k <= 0: | |
| return [] | |
| L = cosine_kernel(E, eps) | |
| chosen: list[int] = [] | |
| for _ in range(k): | |
| best_gain, best_i = -np.inf, -1 | |
| for i in range(G): | |
| if i in chosen: | |
| continue | |
| cand = chosen + [i] | |
| vol = _logdet_psd(L[np.ix_(cand, cand)]) | |
| gain = quality[cand].sum() + lam * vol | |
| if gain > best_gain: | |
| best_gain, best_i = gain, i | |
| if best_i < 0: | |
| break | |
| chosen.append(best_i) | |
| return chosen | |
| def group_metrics(E: np.ndarray, eps: float = EPS_JITTER) -> dict: | |
| """Bundle of reporting metrics for one group. Metrics only, not rewards.""" | |
| E = np.asarray(E, dtype=np.float64) | |
| G = E.shape[0] | |
| if G < 2: | |
| return {"n": G, "mean_pairwise_dist": 0.0, "logdet": 0.0, | |
| "mean_marginal": 0.0, "min_marginal": 0.0} | |
| d = pairwise_deviation(E) | |
| m = marginal_contributions(E, eps) | |
| return { | |
| "n": G, | |
| "mean_pairwise_dist": float(d.mean()), | |
| "logdet": float(logdet_volume(E, eps)), | |
| "mean_marginal": float(m.mean()), | |
| "min_marginal": float(m.min()), | |
| } | |