optimizations for normal llama
Browse files- hexstate_quantize.c +130 -614
- hexstate_requantize.py +205 -587
hexstate_quantize.c
CHANGED
|
@@ -1761,76 +1761,39 @@ static const int Q4_CAND_TO_QUHIT[Q4_N_CAND] = {
|
|
| 1761 |
*
|
| 1762 |
* E(block) = Ξ£α΅’ wα΅’eα΅’Β²
|
| 1763 |
* + (HEX_DC_LAMBDA / n) Β· (Ξ£α΅’eα΅’)Β²
|
| 1764 |
-
* + (HEX_VW_LAMBDA / n) Β· Ξ£
|
| 1765 |
*
|
| 1766 |
-
*
|
| 1767 |
-
*
|
| 1768 |
-
*
|
| 1769 |
-
*
|
| 1770 |
-
*
|
| 1771 |
-
*
|
| 1772 |
-
* applied CONSISTENTLY to: Q2_K/Q4_0 candidate scoring, the closed-form
|
| 1773 |
-
* (d, dmin) refit acceptance, the shaping accept guards, every polish
|
| 1774 |
-
* move, and the Phase-4.7 floor β so no stage optimises a different
|
| 1775 |
-
* objective than its acceptance test measures. The closed-form solvers
|
| 1776 |
-
* incorporate the DC term as a rank-1 augmented observation and act as
|
| 1777 |
-
* proposal generators; acceptance always uses the full extended E.
|
| 1778 |
-
* Ξ» = 0 on both knobs reduces exactly to the pure weighted-SSE objective.
|
| 1779 |
-
* Positive-definiteness: the fold coupling adds Β±2Ξ»_vw/n off-diagonal β
|
| 1780 |
-
* negligible against any sane wα΅’, so E stays a valid quadratic objective.
|
| 1781 |
-
* NOTE: reported RMSE stays pure reconstruction RMSE; with Ξ» > 0 a small
|
| 1782 |
-
* RMSE increase is the *intended* price for lower output error. Per-block
|
| 1783 |
-
* terms are a proxy for row-level structure (the API sees a flat stream);
|
| 1784 |
-
* the Phase-3.9 rolling-DC pass handles cross-block linkage. */
|
| 1785 |
#ifndef HEX_DC_LAMBDA_DEFAULT
|
| 1786 |
-
#define HEX_DC_LAMBDA_DEFAULT
|
| 1787 |
#endif
|
| 1788 |
#ifndef HEX_VW_LAMBDA_DEFAULT
|
| 1789 |
-
#define HEX_VW_LAMBDA_DEFAULT
|
| 1790 |
#endif
|
| 1791 |
#ifndef HEX_DC_DECAY_DEFAULT
|
| 1792 |
-
#define HEX_DC_DECAY_DEFAULT
|
| 1793 |
#endif
|
| 1794 |
-
|
| 1795 |
-
|
| 1796 |
-
|
| 1797 |
-
|
| 1798 |
-
|
| 1799 |
-
|
| 1800 |
-
* Python via hexstate_set_spectral_params. Ξ» = 0, 0 recovers pure
|
| 1801 |
-
* weighted SSE. */
|
| 1802 |
-
|
| 1803 |
-
static float hex_dc_lambda = HEX_DC_LAMBDA_DEFAULT;
|
| 1804 |
-
static float hex_vw_lambda = HEX_VW_LAMBDA_DEFAULT;
|
| 1805 |
-
static float hex_dc_decay = HEX_DC_DECAY_DEFAULT;
|
| 1806 |
-
|
| 1807 |
-
#define HEX_DC_LAMBDA hex_dc_lambda
|
| 1808 |
-
#define HEX_VW_LAMBDA hex_vw_lambda
|
| 1809 |
|
| 1810 |
void hexstate_set_spectral_params(float dc_lambda, float vw_lambda, float dc_decay)
|
| 1811 |
{
|
| 1812 |
-
|
| 1813 |
-
|
| 1814 |
if (dc_decay >= 0.0f && dc_decay <= 1.0f)
|
| 1815 |
-
|
| 1816 |
-
}
|
| 1817 |
-
|
| 1818 |
-
void hexstate_get_spectral_params(float *dc_lambda, float *vw_lambda, float *dc_decay)
|
| 1819 |
-
{
|
| 1820 |
-
if (dc_lambda) *dc_lambda = hex_dc_lambda;
|
| 1821 |
-
if (vw_lambda) *vw_lambda = hex_vw_lambda;
|
| 1822 |
-
if (dc_decay) *dc_decay = hex_dc_decay;
|
| 1823 |
-
}
|
| 1824 |
-
|
| 1825 |
-
/* Spectral penalty of the extended objective for one block: residuals e[n],
|
| 1826 |
-
* fold at n/2. Negative values are possible (anti-phase credit) β the total
|
| 1827 |
-
* E remains positive-definite as argued above. */
|
| 1828 |
-
static inline float hex_spectral_from_moments(float dc, float vesica_ssq, int n)
|
| 1829 |
-
{
|
| 1830 |
-
return (HEX_DC_LAMBDA / (float)n) * dc * dc
|
| 1831 |
-
+ (HEX_VW_LAMBDA / (float)n) * vesica_ssq;
|
| 1832 |
}
|
| 1833 |
|
|
|
|
| 1834 |
static inline float hex_spectral_penalty(const float *e, int n)
|
| 1835 |
{
|
| 1836 |
if (HEX_DC_LAMBDA == 0.0f && HEX_VW_LAMBDA == 0.0f) return 0.0f;
|
|
@@ -1841,434 +1804,8 @@ static inline float hex_spectral_penalty(const float *e, int n)
|
|
| 1841 |
dc += v;
|
| 1842 |
ves += v * v;
|
| 1843 |
}
|
| 1844 |
-
return
|
| 1845 |
-
|
| 1846 |
-
|
| 1847 |
-
#ifndef HEX_VESICA_SSE_EPS
|
| 1848 |
-
#define HEX_VESICA_SSE_EPS 1.0f
|
| 1849 |
-
#endif
|
| 1850 |
-
|
| 1851 |
-
typedef struct { float v; int i; } hex_fold_kv;
|
| 1852 |
-
|
| 1853 |
-
static int hex_fold_kv_cmp(const void *a, const void *b)
|
| 1854 |
-
{
|
| 1855 |
-
const hex_fold_kv *pa = (const hex_fold_kv *)a;
|
| 1856 |
-
const hex_fold_kv *pb = (const hex_fold_kv *)b;
|
| 1857 |
-
if (pa->v < pb->v) return -1;
|
| 1858 |
-
if (pa->v > pb->v) return 1;
|
| 1859 |
-
return pa->i - pb->i;
|
| 1860 |
-
}
|
| 1861 |
-
|
| 1862 |
-
/* Fold's layout, in-place: k-th smallest at k, k-th largest at k+128.
|
| 1863 |
-
* Pair-sum β constant, 16-wide scale groups become homogeneous.
|
| 1864 |
-
* Stored order IS decode order β stock llama, no sidecar. */
|
| 1865 |
-
static void hex_fold_interleave_block(float *x, float *w_row)
|
| 1866 |
-
{
|
| 1867 |
-
hex_fold_kv kv[QK_K];
|
| 1868 |
-
float xt[QK_K], wt[QK_K];
|
| 1869 |
-
memcpy(xt, x, sizeof(xt));
|
| 1870 |
-
if (w_row) memcpy(wt, w_row, sizeof(wt));
|
| 1871 |
-
for (int i = 0; i < QK_K; i++) {
|
| 1872 |
-
kv[i].v = xt[i];
|
| 1873 |
-
kv[i].i = i;
|
| 1874 |
-
}
|
| 1875 |
-
qsort(kv, (size_t)QK_K, sizeof(kv[0]), hex_fold_kv_cmp);
|
| 1876 |
-
int half = QK_K / 2;
|
| 1877 |
-
for (int k = 0; k < half; k++) {
|
| 1878 |
-
int lo = kv[k].i;
|
| 1879 |
-
int hi = kv[QK_K - 1 - k].i;
|
| 1880 |
-
x[k] = xt[lo];
|
| 1881 |
-
x[k + half] = xt[hi];
|
| 1882 |
-
if (w_row) {
|
| 1883 |
-
w_row[k] = wt[lo];
|
| 1884 |
-
w_row[k + half] = wt[hi];
|
| 1885 |
-
}
|
| 1886 |
-
}
|
| 1887 |
-
}
|
| 1888 |
-
|
| 1889 |
-
/* Vesica subcode: among L2-optimal 4x4 points (Edge), pick the one
|
| 1890 |
-
* on the best pair-sum lattice Ο=deq_i+deq_j. Independent nearest-int
|
| 1891 |
-
* breaks those ties without looking at the partner, so the two
|
| 1892 |
-
* estimates of s disagree. Primary SSE, secondary vΒ² β reversing this
|
| 1893 |
-
* was the 0.51 basin. */
|
| 1894 |
-
static void hex_vesica_subcode_q(float xi, float xj,
|
| 1895 |
-
float di, float mi, float dj, float mj,
|
| 1896 |
-
float wi, float wj,
|
| 1897 |
-
int vertex_first,
|
| 1898 |
-
int *qi_out, int *qj_out,
|
| 1899 |
-
float *ei_out, float *ej_out)
|
| 1900 |
-
{
|
| 1901 |
-
float best_sse = 1e30f, best_v = 1e30f;
|
| 1902 |
-
int bqi = 0, bqj = 0;
|
| 1903 |
-
float bei = 0.0f, bej = 0.0f;
|
| 1904 |
-
for (int qi = 0; qi <= 3; qi++) {
|
| 1905 |
-
float deqi = di * (float)qi - mi;
|
| 1906 |
-
float ei = xi - deqi;
|
| 1907 |
-
for (int qj = 0; qj <= 3; qj++) {
|
| 1908 |
-
float deqj = dj * (float)qj - mj;
|
| 1909 |
-
float ej = xj - deqj;
|
| 1910 |
-
float sse = wi * ei * ei + wj * ej * ej;
|
| 1911 |
-
float v2 = (ei + ej) * (ei + ej);
|
| 1912 |
-
int better;
|
| 1913 |
-
if (vertex_first)
|
| 1914 |
-
better = (v2 < best_v - 1e-12f) ||
|
| 1915 |
-
(v2 <= best_v + 1e-12f && sse < best_sse);
|
| 1916 |
-
else
|
| 1917 |
-
better = (sse < best_sse - 1e-12f) ||
|
| 1918 |
-
(sse <= best_sse + 1e-12f && v2 < best_v);
|
| 1919 |
-
if (better) {
|
| 1920 |
-
best_sse = sse;
|
| 1921 |
-
best_v = v2;
|
| 1922 |
-
bqi = qi;
|
| 1923 |
-
bqj = qj;
|
| 1924 |
-
bei = ei;
|
| 1925 |
-
bej = ej;
|
| 1926 |
-
}
|
| 1927 |
-
}
|
| 1928 |
-
}
|
| 1929 |
-
*qi_out = bqi;
|
| 1930 |
-
*qj_out = bqj;
|
| 1931 |
-
*ei_out = bei;
|
| 1932 |
-
*ej_out = bej;
|
| 1933 |
-
}
|
| 1934 |
-
|
| 1935 |
-
static void hex_vesica_bake_subcodes(const float *x, const float *w_row,
|
| 1936 |
-
float dm, float mm,
|
| 1937 |
-
const uint8_t *Ls, const uint8_t *Lm,
|
| 1938 |
-
uint8_t *L, int vertex_first)
|
| 1939 |
-
{
|
| 1940 |
-
for (int p = 0; p < QK_K / 2; p++) {
|
| 1941 |
-
int i = p, j = p + QK_K / 2;
|
| 1942 |
-
int si = i >> 4, sj = j >> 4;
|
| 1943 |
-
float di = dm * (float)Ls[si], mi = mm * (float)Lm[si];
|
| 1944 |
-
float dj = dm * (float)Ls[sj], mj = mm * (float)Lm[sj];
|
| 1945 |
-
float wi = w_row ? w_row[i] : 1.0f;
|
| 1946 |
-
float wj = w_row ? w_row[j] : 1.0f;
|
| 1947 |
-
int qi, qj;
|
| 1948 |
-
float ei, ej;
|
| 1949 |
-
hex_vesica_subcode_q(x[i], x[j], di, mi, dj, mj, wi, wj, vertex_first,
|
| 1950 |
-
&qi, &qj, &ei, &ej);
|
| 1951 |
-
L[i] = (uint8_t)qi;
|
| 1952 |
-
L[j] = (uint8_t)qj;
|
| 1953 |
-
}
|
| 1954 |
-
}
|
| 1955 |
-
|
| 1956 |
-
static float hex_block_sse(const float *x, const float *w_row,
|
| 1957 |
-
float dm, float mm,
|
| 1958 |
-
const uint8_t *Ls, const uint8_t *Lm,
|
| 1959 |
-
const uint8_t *L)
|
| 1960 |
-
{
|
| 1961 |
-
float sse = 0.0f;
|
| 1962 |
-
for (int j = 0; j < QK_K / 16; j++) {
|
| 1963 |
-
float d_sub = dm * (float)Ls[j];
|
| 1964 |
-
float m_sub = mm * (float)Lm[j];
|
| 1965 |
-
for (int k = 0; k < 16; k++) {
|
| 1966 |
-
int idx = 16 * j + k;
|
| 1967 |
-
float w = w_row ? w_row[idx] : 1.0f;
|
| 1968 |
-
float e = x[idx] - (d_sub * (float)L[idx] - m_sub);
|
| 1969 |
-
sse += w * e * e;
|
| 1970 |
-
}
|
| 1971 |
-
}
|
| 1972 |
-
return sse;
|
| 1973 |
-
}
|
| 1974 |
-
|
| 1975 |
-
static void hex_wls_d_dmin(const float *x, const float *w_row,
|
| 1976 |
-
const uint8_t *Ls, const uint8_t *Lm,
|
| 1977 |
-
const uint8_t *L, float *dm, float *mm)
|
| 1978 |
-
{
|
| 1979 |
-
double Saa = 0, Sab = 0, Sbb = 0, Sxa = 0, Sxb = 0;
|
| 1980 |
-
for (int j = 0; j < QK_K / 16; j++) {
|
| 1981 |
-
float ls_f = (float)Ls[j];
|
| 1982 |
-
float lm_f = (float)Lm[j];
|
| 1983 |
-
for (int k = 0; k < 16; k++) {
|
| 1984 |
-
int idx = 16 * j + k;
|
| 1985 |
-
float xv = x[idx];
|
| 1986 |
-
float w = w_row ? w_row[idx] : 1.0f;
|
| 1987 |
-
float a = ls_f * (float)L[idx];
|
| 1988 |
-
float b = lm_f;
|
| 1989 |
-
Saa += w * a * a;
|
| 1990 |
-
Sab += w * a * b;
|
| 1991 |
-
Sbb += w * b * b;
|
| 1992 |
-
Sxa += w * xv * a;
|
| 1993 |
-
Sxb += w * xv * b;
|
| 1994 |
-
}
|
| 1995 |
-
}
|
| 1996 |
-
double det = Saa * Sbb - Sab * Sab;
|
| 1997 |
-
if (fabs(det) <= 1e-30)
|
| 1998 |
-
return;
|
| 1999 |
-
double d_new = (Sbb * Sxa - Sab * Sxb) / det;
|
| 2000 |
-
double m_new = (Sab * Sxa - Saa * Sxb) / det;
|
| 2001 |
-
if (d_new > 0.0 && d_new < 4.0 * ((double)*dm + 1e-10))
|
| 2002 |
-
*dm = gguf_fp16_to_fp32(gguf_fp32_to_fp16((float)d_new));
|
| 2003 |
-
if (m_new > 0.0 && m_new < 4.0 * ((double)*mm + 1e-10))
|
| 2004 |
-
*mm = gguf_fp16_to_fp32(gguf_fp32_to_fp16((float)m_new));
|
| 2005 |
-
}
|
| 2006 |
-
|
| 2007 |
-
/* Tie complementary (ls,lm) when it lowers 32-weight SSE (Fold's
|
| 2008 |
-
* homogeneous group as ordinary nibbles). Ο-bake + WLS, never Edge
|
| 2009 |
-
* after WLS β that was the mismatched-scalar basin. Keep only if
|
| 2010 |
-
* block SSE drops. */
|
| 2011 |
-
static void hex_vesica_commit(const float *x, const float *w_row,
|
| 2012 |
-
float *dm, float *mm,
|
| 2013 |
-
uint8_t *Ls, uint8_t *Lm, uint8_t *L)
|
| 2014 |
-
{
|
| 2015 |
-
uint8_t L0[QK_K], Ls0[16], Lm0[16];
|
| 2016 |
-
memcpy(L0, L, QK_K);
|
| 2017 |
-
memcpy(Ls0, Ls, 16);
|
| 2018 |
-
memcpy(Lm0, Lm, 16);
|
| 2019 |
-
float dm0 = *dm, mm0 = *mm;
|
| 2020 |
-
float sse0 = hex_block_sse(x, w_row, dm0, mm0, Ls0, Lm0, L0);
|
| 2021 |
-
|
| 2022 |
-
for (int p = 0; p < 8; p++) {
|
| 2023 |
-
int A = p, B = p + 8;
|
| 2024 |
-
uint8_t tLs[16], tLm[16], tL[QK_K];
|
| 2025 |
-
float best32 = 1e30f;
|
| 2026 |
-
uint8_t bA_ls = Ls[A], bA_lm = Lm[A], bB_ls = Ls[B], bB_lm = Lm[B];
|
| 2027 |
-
uint8_t cand_lsA[4] = { Ls[A], Ls[A], Ls[B], (uint8_t)((Ls[A] + Ls[B] + 1) / 2) };
|
| 2028 |
-
uint8_t cand_lmA[4] = { Lm[A], Lm[A], Lm[B], (uint8_t)((Lm[A] + Lm[B] + 1) / 2) };
|
| 2029 |
-
uint8_t cand_lsB[4] = { Ls[B], Ls[A], Ls[B], (uint8_t)((Ls[A] + Ls[B] + 1) / 2) };
|
| 2030 |
-
uint8_t cand_lmB[4] = { Lm[B], Lm[A], Lm[B], (uint8_t)((Lm[A] + Lm[B] + 1) / 2) };
|
| 2031 |
-
for (int t = 0; t < 4; t++) {
|
| 2032 |
-
memcpy(tLs, Ls, 16);
|
| 2033 |
-
memcpy(tLm, Lm, 16);
|
| 2034 |
-
tLs[A] = cand_lsA[t]; tLm[A] = cand_lmA[t];
|
| 2035 |
-
tLs[B] = cand_lsB[t]; tLm[B] = cand_lmB[t];
|
| 2036 |
-
memcpy(tL, L, QK_K);
|
| 2037 |
-
hex_vesica_bake_subcodes(x, w_row, *dm, *mm, tLs, tLm, tL, 0);
|
| 2038 |
-
float s32 = 0.0f;
|
| 2039 |
-
for (int k = 0; k < 16; k++) {
|
| 2040 |
-
int i = 16 * A + k, j = 16 * B + k;
|
| 2041 |
-
float di = *dm * (float)tLs[A], mi = *mm * (float)tLm[A];
|
| 2042 |
-
float dj = *dm * (float)tLs[B], mj = *mm * (float)tLm[B];
|
| 2043 |
-
float ei = x[i] - (di * (float)tL[i] - mi);
|
| 2044 |
-
float ej = x[j] - (dj * (float)tL[j] - mj);
|
| 2045 |
-
float wi = w_row ? w_row[i] : 1.0f;
|
| 2046 |
-
float wj = w_row ? w_row[j] : 1.0f;
|
| 2047 |
-
s32 += wi * ei * ei + wj * ej * ej;
|
| 2048 |
-
}
|
| 2049 |
-
if (s32 < best32) {
|
| 2050 |
-
best32 = s32;
|
| 2051 |
-
bA_ls = tLs[A]; bA_lm = tLm[A];
|
| 2052 |
-
bB_ls = tLs[B]; bB_lm = tLm[B];
|
| 2053 |
-
}
|
| 2054 |
-
}
|
| 2055 |
-
Ls[A] = bA_ls; Lm[A] = bA_lm;
|
| 2056 |
-
Ls[B] = bB_ls; Lm[B] = bB_lm;
|
| 2057 |
-
}
|
| 2058 |
-
|
| 2059 |
-
for (int it = 0; it < 3; it++) {
|
| 2060 |
-
hex_vesica_bake_subcodes(x, w_row, *dm, *mm, Ls, Lm, L, 1);
|
| 2061 |
-
hex_wls_d_dmin(x, w_row, Ls, Lm, L, dm, mm);
|
| 2062 |
-
}
|
| 2063 |
-
hex_vesica_bake_subcodes(x, w_row, *dm, *mm, Ls, Lm, L, 0);
|
| 2064 |
-
|
| 2065 |
-
float sse1 = hex_block_sse(x, w_row, *dm, *mm, Ls, Lm, L);
|
| 2066 |
-
if (!(sse1 < sse0)) {
|
| 2067 |
-
memcpy(L, L0, QK_K);
|
| 2068 |
-
memcpy(Ls, Ls0, 16);
|
| 2069 |
-
memcpy(Lm, Lm0, 16);
|
| 2070 |
-
*dm = dm0;
|
| 2071 |
-
*mm = mm0;
|
| 2072 |
-
}
|
| 2073 |
-
}
|
| 2074 |
-
|
| 2075 |
-
/* Vesica + triality. Cooley-Tukey DFT6 = 2 x 3: antipodal fold is
|
| 2076 |
-
* vesica/wave; the 3-cycle Edge/Vertex/Diagonal is triality_rotate.
|
| 2077 |
-
* Vertex: min v^2 + DC^2 (in-phase / DC floor)
|
| 2078 |
-
* Diagonal: min w^2, keep v and DC (anti-phase / leftover RMSE)
|
| 2079 |
-
* Edge: min SSE, keep v and DC (computational RMSE)
|
| 2080 |
-
* RMSE^2 = (v^2 + w^2)/2 per pair, so Diagonal+Edge shrink RMSE
|
| 2081 |
-
* without giving back the Vertex cancellation. Two sweeps/view. */
|
| 2082 |
-
static void hex_vesica_guide_pairs(const float *x, const float *w_row,
|
| 2083 |
-
float dm, float mm,
|
| 2084 |
-
const uint8_t *Ls, const uint8_t *Lm,
|
| 2085 |
-
uint8_t *L)
|
| 2086 |
-
{
|
| 2087 |
-
float e[QK_K];
|
| 2088 |
-
float dc = 0.0f;
|
| 2089 |
-
for (int i = 0; i < QK_K; i++) {
|
| 2090 |
-
int s = i >> 4;
|
| 2091 |
-
float d_s = dm * (float)Ls[s];
|
| 2092 |
-
float m_s = mm * (float)Lm[s];
|
| 2093 |
-
e[i] = x[i] - (d_s * (float)L[i] - m_s);
|
| 2094 |
-
dc += e[i];
|
| 2095 |
-
}
|
| 2096 |
-
|
| 2097 |
-
/* Vertex (vesica+DC), then Edge (RMSE with vesica/DC held).
|
| 2098 |
-
* Diagonal/wave is implied: RMSE^2 = (v^2+w^2)/2 at fixed v. */
|
| 2099 |
-
for (int rot = 0; rot < 2; rot++) {
|
| 2100 |
-
for (int sweep = 0; sweep < 2; sweep++) {
|
| 2101 |
-
for (int p = 0; p < QK_K / 2; p++) {
|
| 2102 |
-
int i = p, j = p + QK_K / 2;
|
| 2103 |
-
int si = i >> 4, sj = j >> 4;
|
| 2104 |
-
float di = dm * (float)Ls[si], mi = mm * (float)Lm[si];
|
| 2105 |
-
float dj = dm * (float)Ls[sj], mj = mm * (float)Lm[sj];
|
| 2106 |
-
float wi = w_row ? w_row[i] : 1.0f;
|
| 2107 |
-
float wj = w_row ? w_row[j] : 1.0f;
|
| 2108 |
-
|
| 2109 |
-
int q0i = 0, q0j = 0;
|
| 2110 |
-
if (di >= 1e-15f) {
|
| 2111 |
-
q0i = gguf_nearest_int((x[i] + mi) / di);
|
| 2112 |
-
if (q0i < 0) q0i = 0; if (q0i > 3) q0i = 3;
|
| 2113 |
-
}
|
| 2114 |
-
if (dj >= 1e-15f) {
|
| 2115 |
-
q0j = gguf_nearest_int((x[j] + mj) / dj);
|
| 2116 |
-
if (q0j < 0) q0j = 0; if (q0j > 3) q0j = 3;
|
| 2117 |
-
}
|
| 2118 |
-
|
| 2119 |
-
float v_old = e[i] + e[j];
|
| 2120 |
-
float dc_rest = dc - v_old;
|
| 2121 |
-
float dc_abs0 = dc * dc;
|
| 2122 |
-
float ves0 = v_old * v_old;
|
| 2123 |
-
float cur_sse = wi * e[i] * e[i] + wj * e[j] * e[j];
|
| 2124 |
-
float best = (rot == 0) ? 1e30f : cur_sse;
|
| 2125 |
-
int bqi = (int)L[i], bqj = (int)L[j];
|
| 2126 |
-
float bei = e[i], bej = e[j];
|
| 2127 |
-
|
| 2128 |
-
int qi0 = q0i - 1, qi1 = q0i + 1;
|
| 2129 |
-
int qj0 = q0j - 1, qj1 = q0j + 1;
|
| 2130 |
-
if (qi0 < 0) qi0 = 0; if (qi1 > 3) qi1 = 3;
|
| 2131 |
-
if (qj0 < 0) qj0 = 0; if (qj1 > 3) qj1 = 3;
|
| 2132 |
-
|
| 2133 |
-
for (int qi = qi0; qi <= qi1; qi++) {
|
| 2134 |
-
float ei = x[i] - (di * (float)qi - mi);
|
| 2135 |
-
for (int qj = qj0; qj <= qj1; qj++) {
|
| 2136 |
-
float ej = x[j] - (dj * (float)qj - mj);
|
| 2137 |
-
float v = ei + ej;
|
| 2138 |
-
float sse = wi * ei * ei + wj * ej * ej;
|
| 2139 |
-
float dc_n = dc_rest + v;
|
| 2140 |
-
float sc;
|
| 2141 |
-
if (rot == 0)
|
| 2142 |
-
sc = v * v + dc_n * dc_n
|
| 2143 |
-
+ HEX_VESICA_SSE_EPS * sse;
|
| 2144 |
-
else {
|
| 2145 |
-
/* Edge: cut RMSE only if vesica and DC do not grow. */
|
| 2146 |
-
if (v * v > ves0 * 1.05f) continue;
|
| 2147 |
-
if (dc_n * dc_n > dc_abs0 * 1.05f) continue;
|
| 2148 |
-
sc = sse;
|
| 2149 |
-
}
|
| 2150 |
-
if (sc < best) {
|
| 2151 |
-
best = sc;
|
| 2152 |
-
bqi = qi; bqj = qj;
|
| 2153 |
-
bei = ei; bej = ej;
|
| 2154 |
-
}
|
| 2155 |
-
}
|
| 2156 |
-
}
|
| 2157 |
-
L[i] = (uint8_t)bqi;
|
| 2158 |
-
L[j] = (uint8_t)bqj;
|
| 2159 |
-
dc = dc_rest + bei + bej;
|
| 2160 |
-
e[i] = bei;
|
| 2161 |
-
e[j] = bej;
|
| 2162 |
-
}
|
| 2163 |
-
}
|
| 2164 |
-
}
|
| 2165 |
-
}
|
| 2166 |
-
|
| 2167 |
-
/* Joint HPC-graph decode of a vesica sub-block pair (A, A^8).
|
| 2168 |
-
* Edge 4x4 is L2-optimal codes for a fixed scale pair and is separable.
|
| 2169 |
-
* Vertex (Ξ£vΒ²) and DCΒ² on the 32-weight group are not: they couple the
|
| 2170 |
-
* two HPC 6-states. Fold's RMSE win is that pair-sum; scoring
|
| 2171 |
-
* Edge SSE + Ξ»_vw Vertex + Ξ»_dc DCΒ²
|
| 2172 |
-
* picks complementary (ls,lm) so WLS (d, dmin) sees one s, not two.
|
| 2173 |
-
* Stock layout, no permutation. */
|
| 2174 |
-
static void hex_joint_fold_subpairs(const float *x, const float *w_row,
|
| 2175 |
-
float dm, float mm,
|
| 2176 |
-
uint8_t state_ls[][6], uint8_t state_lm[][6],
|
| 2177 |
-
uint8_t *Ls, uint8_t *Lm, uint8_t *L)
|
| 2178 |
-
{
|
| 2179 |
-
for (int p = 0; p < 8; p++) {
|
| 2180 |
-
int A = p, B = p + 8;
|
| 2181 |
-
float best = 1e30f;
|
| 2182 |
-
int bva = 0, bvb = 0;
|
| 2183 |
-
uint8_t bqA[16], bqB[16];
|
| 2184 |
-
|
| 2185 |
-
for (int va = 0; va < 6; va++) {
|
| 2186 |
-
float dA = dm * (float)state_ls[A][va];
|
| 2187 |
-
float mA = mm * (float)state_lm[A][va];
|
| 2188 |
-
for (int vb = 0; vb < 6; vb++) {
|
| 2189 |
-
float dB = dm * (float)state_ls[B][vb];
|
| 2190 |
-
float mB = mm * (float)state_lm[B][vb];
|
| 2191 |
-
float sse = 0.0f, ves = 0.0f, dcg = 0.0f;
|
| 2192 |
-
uint8_t qA[16], qB[16];
|
| 2193 |
-
for (int k = 0; k < 16; k++) {
|
| 2194 |
-
int i = 16 * A + k;
|
| 2195 |
-
int j = 16 * B + k;
|
| 2196 |
-
float wi = w_row ? w_row[i] : 1.0f;
|
| 2197 |
-
float wj = w_row ? w_row[j] : 1.0f;
|
| 2198 |
-
float bestp = 1e30f;
|
| 2199 |
-
int bqi = 0, bqj = 0;
|
| 2200 |
-
float bei = 0.0f, bej = 0.0f;
|
| 2201 |
-
for (int qi = 0; qi <= 3; qi++) {
|
| 2202 |
-
float ei = x[i] - (dA * (float)qi - mA);
|
| 2203 |
-
for (int qj = 0; qj <= 3; qj++) {
|
| 2204 |
-
float ej = x[j] - (dB * (float)qj - mB);
|
| 2205 |
-
float sc = wi * ei * ei + wj * ej * ej;
|
| 2206 |
-
if (sc < bestp) {
|
| 2207 |
-
bestp = sc;
|
| 2208 |
-
bqi = qi;
|
| 2209 |
-
bqj = qj;
|
| 2210 |
-
bei = ei;
|
| 2211 |
-
bej = ej;
|
| 2212 |
-
}
|
| 2213 |
-
}
|
| 2214 |
-
}
|
| 2215 |
-
qA[k] = (uint8_t)bqi;
|
| 2216 |
-
qB[k] = (uint8_t)bqj;
|
| 2217 |
-
sse += bestp;
|
| 2218 |
-
ves += (bei + bej) * (bei + bej);
|
| 2219 |
-
dcg += bei + bej;
|
| 2220 |
-
}
|
| 2221 |
-
float sc = HEX_VESICA_SSE_EPS * sse
|
| 2222 |
-
+ HEX_VW_LAMBDA * ves
|
| 2223 |
-
+ HEX_DC_LAMBDA * dcg * dcg;
|
| 2224 |
-
if (sc < best) {
|
| 2225 |
-
best = sc;
|
| 2226 |
-
bva = va;
|
| 2227 |
-
bvb = vb;
|
| 2228 |
-
memcpy(bqA, qA, 16);
|
| 2229 |
-
memcpy(bqB, qB, 16);
|
| 2230 |
-
}
|
| 2231 |
-
}
|
| 2232 |
-
}
|
| 2233 |
-
Ls[A] = state_ls[A][bva];
|
| 2234 |
-
Lm[A] = state_lm[A][bva];
|
| 2235 |
-
Ls[B] = state_ls[B][bvb];
|
| 2236 |
-
Lm[B] = state_lm[B][bvb];
|
| 2237 |
-
memcpy(L + 16 * A, bqA, 16);
|
| 2238 |
-
memcpy(L + 16 * B, bqB, 16);
|
| 2239 |
-
}
|
| 2240 |
-
}
|
| 2241 |
-
|
| 2242 |
-
/* Edge 4x4 on every fold pair for committed (d, dmin, Ls, Lm). */
|
| 2243 |
-
static void hex_pair_edge_codes(const float *x, const float *w_row,
|
| 2244 |
-
float dm, float mm,
|
| 2245 |
-
const uint8_t *Ls, const uint8_t *Lm,
|
| 2246 |
-
uint8_t *L)
|
| 2247 |
-
{
|
| 2248 |
-
for (int p = 0; p < QK_K / 2; p++) {
|
| 2249 |
-
int i = p, j = p + QK_K / 2;
|
| 2250 |
-
int si = i >> 4, sj = j >> 4;
|
| 2251 |
-
float di = dm * (float)Ls[si], mi = mm * (float)Lm[si];
|
| 2252 |
-
float dj = dm * (float)Ls[sj], mj = mm * (float)Lm[sj];
|
| 2253 |
-
float wi = w_row ? w_row[i] : 1.0f;
|
| 2254 |
-
float wj = w_row ? w_row[j] : 1.0f;
|
| 2255 |
-
float best = 1e30f;
|
| 2256 |
-
int bqi = 0, bqj = 0;
|
| 2257 |
-
for (int qi = 0; qi <= 3; qi++) {
|
| 2258 |
-
float ei = x[i] - (di * (float)qi - mi);
|
| 2259 |
-
for (int qj = 0; qj <= 3; qj++) {
|
| 2260 |
-
float ej = x[j] - (dj * (float)qj - mj);
|
| 2261 |
-
float sc = wi * ei * ei + wj * ej * ej;
|
| 2262 |
-
if (sc < best) {
|
| 2263 |
-
best = sc;
|
| 2264 |
-
bqi = qi;
|
| 2265 |
-
bqj = qj;
|
| 2266 |
-
}
|
| 2267 |
-
}
|
| 2268 |
-
}
|
| 2269 |
-
L[i] = (uint8_t)bqi;
|
| 2270 |
-
L[j] = (uint8_t)bqj;
|
| 2271 |
-
}
|
| 2272 |
}
|
| 2273 |
|
| 2274 |
/* Robust temperature estimator for the HExState measurement model.
|
|
@@ -2905,14 +2442,13 @@ static void quantize_tensor_q4_0_hpc(const float *weights, int64_t n_elements,
|
|
| 2905 |
}
|
| 2906 |
|
| 2907 |
float v_live[QK4_0 / 2];
|
| 2908 |
-
float vesica_cur = 0.0f, dc_cur = 0.0f
|
| 2909 |
for (int j = 0; j < QK4_0 / 2; j++) {
|
| 2910 |
v_live[j] = e_live[j] + e_live[j + QK4_0 / 2];
|
| 2911 |
vesica_cur += v_live[j] * v_live[j];
|
| 2912 |
-
cross_cur += e_live[j] * e_live[j + QK4_0 / 2];
|
| 2913 |
}
|
| 2914 |
for (int j = 0; j < QK4_0; j++) dc_cur += e_live[j];
|
| 2915 |
-
float metric_cur =
|
| 2916 |
|
| 2917 |
/* Deterministic greedy descent: only strict improvements.
|
| 2918 |
* The previous SA acceptance called rand() inside an OpenMP
|
|
@@ -2942,7 +2478,7 @@ static void quantize_tensor_q4_0_hpc(const float *weights, int64_t n_elements,
|
|
| 2942 |
|
| 2943 |
float vesica_alt = vesica_cur - v_old * v_old + v_new * v_new;
|
| 2944 |
float dc_alt = dc_cur + de;
|
| 2945 |
-
float metric_alt =
|
| 2946 |
|
| 2947 |
float delta = metric_cur - metric_alt;
|
| 2948 |
if (delta > best_delta) {
|
|
@@ -2966,7 +2502,7 @@ static void quantize_tensor_q4_0_hpc(const float *weights, int64_t n_elements,
|
|
| 2966 |
|
| 2967 |
vesica_cur += v_new_commit * v_new_commit - v_old_commit * v_old_commit;
|
| 2968 |
dc_cur += de_commit;
|
| 2969 |
-
metric_cur =
|
| 2970 |
|
| 2971 |
v_live[pi_commit] = v_new_commit;
|
| 2972 |
e_live[best_k] = e_new_commit;
|
|
@@ -3277,16 +2813,15 @@ static void quantize_tensor_q8_0_hpc(const float *weights, int64_t n_elements,
|
|
| 3277 |
int8_t qs_shaped[QK8_0];
|
| 3278 |
memcpy(qs_shaped, qs, QK8_0);
|
| 3279 |
float e_live[QK8_0], v_live[QK8_0 / 2];
|
| 3280 |
-
float vesica_cur = 0.0f, dc_cur = 0.0f
|
| 3281 |
for (int k = 0; k < QK8_0; k++)
|
| 3282 |
e_live[k] = bw[k] - (float)qs_shaped[k] * d;
|
| 3283 |
for (int p = 0; p < QK8_0 / 2; p++) {
|
| 3284 |
v_live[p] = e_live[p] + e_live[p + QK8_0 / 2];
|
| 3285 |
vesica_cur += v_live[p] * v_live[p];
|
| 3286 |
-
cross_cur += e_live[p] * e_live[p + QK8_0 / 2];
|
| 3287 |
dc_cur += v_live[p];
|
| 3288 |
}
|
| 3289 |
-
float metric_cur =
|
| 3290 |
for (int pass = 0; pass < QK8_0; pass++) {
|
| 3291 |
int best_k = -1, best_q_alt = 0;
|
| 3292 |
float best_delta = 0.0f;
|
|
@@ -3301,8 +2836,7 @@ static void quantize_tensor_q8_0_hpc(const float *weights, int64_t n_elements,
|
|
| 3301 |
float ves_a = vesica_cur - v_live[pi] * v_live[pi]
|
| 3302 |
+ v_new * v_new;
|
| 3303 |
float dc_a = dc_cur + de;
|
| 3304 |
-
float delta = metric_cur
|
| 3305 |
-
- hex_spectral_from_moments(dc_a, ves_a, QK8_0);
|
| 3306 |
if (delta > best_delta) {
|
| 3307 |
best_delta = delta; best_k = k; best_q_alt = q_try;
|
| 3308 |
}
|
|
@@ -3316,7 +2850,7 @@ static void quantize_tensor_q8_0_hpc(const float *weights, int64_t n_elements,
|
|
| 3316 |
float v_new = v_live[pi] + de;
|
| 3317 |
vesica_cur += v_new * v_new - v_live[pi] * v_live[pi];
|
| 3318 |
dc_cur += de;
|
| 3319 |
-
metric_cur =
|
| 3320 |
v_live[pi] = v_new;
|
| 3321 |
e_live[best_k] = e_new;
|
| 3322 |
qs_shaped[best_k] = (int8_t)best_q_alt;
|
|
@@ -4101,6 +3635,8 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4101 |
* this array (safe: written sequentially before the parallel loop).
|
| 4102 |
* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 4103 |
|
|
|
|
|
|
|
| 4104 |
float *block_dc_bias = (float *)calloc(n_blocks, sizeof(float));
|
| 4105 |
|
| 4106 |
if (block_dc_bias) {
|
|
@@ -4129,7 +3665,7 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4129 |
dm0, mm0, dc_Ls, dc_Lm);
|
| 4130 |
|
| 4131 |
/* Bias applied to THIS block's WLS targets */
|
| 4132 |
-
float dc_bias = (
|
| 4133 |
block_dc_bias[blk] = dc_bias;
|
| 4134 |
|
| 4135 |
/* Quick round-nearest quant to estimate DC residual for NEXT block.
|
|
@@ -4201,7 +3737,6 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4201 |
uint16_t prev_dm16 = 0, prev_mm16 = 0;
|
| 4202 |
for (int ls_iter = 0; ls_iter < 5; ls_iter++) {
|
| 4203 |
|
| 4204 |
-
uint8_t L[QK_K];
|
| 4205 |
uint8_t state_ls[N_SUB][6];
|
| 4206 |
uint8_t state_lm[N_SUB][6];
|
| 4207 |
float state_err[N_SUB][6];
|
|
@@ -4284,11 +3819,6 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4284 |
|
| 4285 |
for (int j = 0; j < N_SUB - 1; j++)
|
| 4286 |
hpc_cz(sg, j, j + 1);
|
| 4287 |
-
/* Vesica partners (sub j <-> j^8) share fold pairs i <-> i+128.
|
| 4288 |
-
* Entangle them so sieve back-action diversifies complementary
|
| 4289 |
-
* bins (triality pair: each view of one is a role of the other). */
|
| 4290 |
-
for (int j = 0; j < 8; j++)
|
| 4291 |
-
hpc_cz(sg, j, j + 8);
|
| 4292 |
|
| 4293 |
double sub_marg[N_SUB][6];
|
| 4294 |
int sub_measured[N_SUB];
|
|
@@ -4297,11 +3827,33 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4297 |
|
| 4298 |
sieve_measure_graph(sg, N_SUB, sub_marg, sub_measured, 1);
|
| 4299 |
|
| 4300 |
-
|
| 4301 |
-
|
| 4302 |
-
|
| 4303 |
-
|
| 4304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4305 |
}
|
| 4306 |
|
| 4307 |
double Saa = 0, Sab = 0, Sbb = 0, Sxa = 0, Sxb = 0;
|
|
@@ -4365,7 +3917,7 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4365 |
float d_sub = trial_dm * (float)Ls_blk[j];
|
| 4366 |
float m_sub = trial_mm * (float)Lm_blk[j];
|
| 4367 |
for (int k = 0; k < 16; k++) {
|
| 4368 |
-
float x =
|
| 4369 |
float w = (imat_importance) ?
|
| 4370 |
imat_importance[blk * QK_K + 16*j+k] : 1.0f;
|
| 4371 |
int q;
|
|
@@ -4391,7 +3943,7 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4391 |
}
|
| 4392 |
|
| 4393 |
for (int j = 0; j < N_SUB; j++) {
|
| 4394 |
-
const float *sx =
|
| 4395 |
float best_sub_err = 1e30f;
|
| 4396 |
uint8_t best_ls = Ls_blk[j], best_lm = Lm_blk[j];
|
| 4397 |
for (int try_ls = 0; try_ls <= 15; try_ls++) {
|
|
@@ -4446,45 +3998,50 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4446 |
*/
|
| 4447 |
uint8_t L[QK_K];
|
| 4448 |
{
|
| 4449 |
-
|
| 4450 |
-
|
| 4451 |
-
|
| 4452 |
-
|
| 4453 |
-
int
|
| 4454 |
-
|
| 4455 |
-
|
| 4456 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4457 |
memcpy(q_shaped_all, q_base_all, QK_K * sizeof(int));
|
| 4458 |
|
| 4459 |
float e_live[QK_K];
|
|
|
|
| 4460 |
for (int i = 0; i < QK_K; i++) {
|
| 4461 |
int jj = i >> 4;
|
| 4462 |
float d_s = dm * (float)(output[blk].scales[jj] & 0xF);
|
| 4463 |
float m_s = mm * (float)(output[blk].scales[jj] >> 4);
|
| 4464 |
-
/* Decoder semantics: deq = d_sΒ·q β m_s, which is βm_s when
|
| 4465 |
-
* d_s == 0 (NOT 0 β the βdminΒ·lm term always applies). */
|
| 4466 |
float deq = d_s * (float)q_shaped_all[i] - m_s;
|
| 4467 |
-
/*
|
|
|
|
| 4468 |
e_live[i] = block_x[i] - deq;
|
|
|
|
| 4469 |
}
|
| 4470 |
|
| 4471 |
float v_live[QK_K / 2];
|
| 4472 |
-
float vesica_cur = 0.0f
|
| 4473 |
for (int i = 0; i < QK_K / 2; i++) {
|
| 4474 |
v_live[i] = e_live[i] + e_live[i + QK_K / 2];
|
| 4475 |
vesica_cur += v_live[i] * v_live[i];
|
| 4476 |
-
cross_cur += e_live[i] * e_live[i + QK_K / 2];
|
| 4477 |
}
|
| 4478 |
-
|
| 4479 |
-
float sse_cur = 0.0f;
|
| 4480 |
-
for (int i = 0; i < QK_K; i++) {
|
| 4481 |
-
float w = (imat_importance) ? imat_importance[blk * QK_K + i] : 1.0f;
|
| 4482 |
-
sse_cur += w * e_live[i] * e_live[i];
|
| 4483 |
-
}
|
| 4484 |
-
float metric_cur = HEX_VESICA_SSE_EPS * sse_cur
|
| 4485 |
-
+ hex_spectral_from_moments(dc_cur, vesica_cur, QK_K);
|
| 4486 |
|
| 4487 |
-
/* Deterministic greedy:
|
| 4488 |
for (int pass = 0; pass < QK_K; pass++) {
|
| 4489 |
int best_k = -1;
|
| 4490 |
int best_q_alt = 0;
|
|
@@ -4498,8 +4055,11 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4498 |
int q_cur = q_shaped_all[k];
|
| 4499 |
float m_s = mm * (float)(output[blk].scales[jj] >> 4);
|
| 4500 |
int pi = (k < QK_K / 2) ? k : k - QK_K / 2;
|
| 4501 |
-
float wk = (imat_importance) ? imat_importance[blk * QK_K + k] : 1.0f;
|
| 4502 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4503 |
for (int q_try = 0; q_try <= 3; q_try++) {
|
| 4504 |
if (q_try == q_cur) continue;
|
| 4505 |
|
|
@@ -4510,12 +4070,7 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4510 |
|
| 4511 |
float vesica_alt = vesica_cur - v_live[pi]*v_live[pi] + v_new*v_new;
|
| 4512 |
float dc_alt = dc_cur + de;
|
| 4513 |
-
float
|
| 4514 |
-
- wk * e_live[k] * e_live[k]
|
| 4515 |
-
+ wk * e_new * e_new;
|
| 4516 |
-
float met_alt = HEX_VESICA_SSE_EPS * sse_alt
|
| 4517 |
-
+ hex_spectral_from_moments(dc_alt, vesica_alt, QK_K);
|
| 4518 |
-
float delta = metric_cur - met_alt;
|
| 4519 |
|
| 4520 |
if (delta > best_delta) {
|
| 4521 |
best_delta = delta;
|
|
@@ -4536,14 +4091,9 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4536 |
float de_c = e_new_c - e_live[best_k];
|
| 4537 |
int pi_c = (best_k < QK_K / 2) ? best_k : best_k - QK_K / 2;
|
| 4538 |
float v_new_c = v_live[pi_c] + de_c;
|
| 4539 |
-
float wk_c = (imat_importance)
|
| 4540 |
-
? imat_importance[blk * QK_K + best_k] : 1.0f;
|
| 4541 |
-
sse_cur += wk_c * (e_new_c * e_new_c
|
| 4542 |
-
- e_live[best_k] * e_live[best_k]);
|
| 4543 |
vesica_cur += v_new_c * v_new_c - v_live[pi_c] * v_live[pi_c];
|
| 4544 |
dc_cur += de_c;
|
| 4545 |
-
metric_cur =
|
| 4546 |
-
+ hex_spectral_from_moments(dc_cur, vesica_cur, QK_K);
|
| 4547 |
v_live[pi_c] = v_new_c;
|
| 4548 |
e_live[best_k]= e_new_c;
|
| 4549 |
}
|
|
@@ -4888,8 +4438,8 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4888 |
int pi = j & 7; /* fold-pair index */
|
| 4889 |
int pj = j ^ 8; /* partner sub-block */
|
| 4890 |
const float *ppe = pe + 16 * pj; /* partner residuals */
|
| 4891 |
-
float dc_rest = dc_tot
|
| 4892 |
-
float ves_rest = ves_tot
|
| 4893 |
|
| 4894 |
/* Extended score of the CURRENT committed state */
|
| 4895 |
float best_sub = sub_sse[j]
|
|
@@ -4898,13 +4448,13 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4898 |
int best_ls = -1, best_lm = 0;
|
| 4899 |
uint8_t best_q[16];
|
| 4900 |
float best_e[16];
|
| 4901 |
-
float best_sse = 0.0f, best_dcc = 0.0f,
|
| 4902 |
|
| 4903 |
for (int try_ls = 0; try_ls <= 15; try_ls++) {
|
| 4904 |
float d_sub = dm * (float)try_ls;
|
| 4905 |
for (int try_lm = 0; try_lm <= 15; try_lm++) {
|
| 4906 |
float m_sub = mm * (float)try_lm;
|
| 4907 |
-
float sub_err = 0.0f, dcc = 0.0f,
|
| 4908 |
uint8_t q_loc[16];
|
| 4909 |
float e_loc[16];
|
| 4910 |
int aborted = 0;
|
|
@@ -4918,24 +4468,23 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4918 |
if (q < 0) q = 0; if (q > 3) q = 3;
|
| 4919 |
}
|
| 4920 |
q_loc[k] = (uint8_t)q;
|
| 4921 |
-
/* deq = dΒ·lsΒ·q β dminΒ·lm; βm_sub at ls==0 */
|
| 4922 |
float e = x - (d_sub * (float)q - m_sub);
|
| 4923 |
e_loc[k] = e;
|
| 4924 |
sub_err += e * e * w;
|
| 4925 |
dcc += e;
|
| 4926 |
{
|
| 4927 |
-
float
|
| 4928 |
-
|
| 4929 |
}
|
| 4930 |
-
|
| 4931 |
-
|
| 4932 |
}
|
| 4933 |
if (aborted) continue;
|
| 4934 |
float score = sub_err
|
| 4935 |
+ (HEX_DC_LAMBDA / (float)QK_K)
|
| 4936 |
* (dc_rest + dcc) * (dc_rest + dcc)
|
| 4937 |
+ (HEX_VW_LAMBDA / (float)QK_K)
|
| 4938 |
-
* (ves_rest +
|
| 4939 |
if (score < best_sub) {
|
| 4940 |
best_sub = score;
|
| 4941 |
best_ls = try_ls;
|
|
@@ -4944,7 +4493,7 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4944 |
memcpy(best_e, e_loc, sizeof(e_loc));
|
| 4945 |
best_sse = sub_err;
|
| 4946 |
best_dcc = dcc;
|
| 4947 |
-
|
| 4948 |
}
|
| 4949 |
}
|
| 4950 |
}
|
|
@@ -4954,11 +4503,11 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 4954 |
pl_Lm[j] = (uint8_t)best_lm;
|
| 4955 |
memcpy(L + 16 * j, best_q, 16);
|
| 4956 |
memcpy(pe + 16 * j, best_e, sizeof(best_e));
|
| 4957 |
-
sub_sse[j]
|
| 4958 |
-
sub_dc[j]
|
| 4959 |
-
pair_ves[pi]
|
| 4960 |
-
dc_tot
|
| 4961 |
-
ves_tot
|
| 4962 |
pol_improved = 1;
|
| 4963 |
}
|
| 4964 |
}
|
|
@@ -5075,11 +4624,8 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 5075 |
float t_mm = gguf_fp16_to_fp32((uint16_t)cm16);
|
| 5076 |
|
| 5077 |
float err = 0.0f;
|
| 5078 |
-
|
| 5079 |
-
|
| 5080 |
-
for (int j = 0;
|
| 5081 |
-
j < N_SUB && (HEX_VW_LAMBDA != 0.0f ||
|
| 5082 |
-
err < best_err); j++) {
|
| 5083 |
float d_sub = t_dm * (float)pl_Ls[j];
|
| 5084 |
float m_sub = t_mm * (float)pl_Lm[j];
|
| 5085 |
for (int k = 0; k < 16; k++) {
|
|
@@ -5090,11 +4636,10 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 5090 |
(d_sub * (float)L[idx] - m_sub);
|
| 5091 |
err += e_u[idx] * e_u[idx] * w;
|
| 5092 |
}
|
|
|
|
| 5093 |
}
|
| 5094 |
-
if (
|
| 5095 |
-
|
| 5096 |
-
? err + hex_spectral_penalty(e_u, QK_K)
|
| 5097 |
-
: err;
|
| 5098 |
if (err < best_err) {
|
| 5099 |
best_err = err;
|
| 5100 |
best_d16 = (uint16_t)cd16;
|
|
@@ -5119,34 +4664,20 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 5119 |
output[blk].dmin = gguf_fp32_to_fp16(mm);
|
| 5120 |
}
|
| 5121 |
|
| 5122 |
-
/*
|
| 5123 |
-
* Accept only if block SSE drops; 4.7 is the backstop. */
|
| 5124 |
-
{
|
| 5125 |
-
uint8_t gLs[16], gLm[16];
|
| 5126 |
-
const float *wrow = imat_importance
|
| 5127 |
-
? (imat_importance + blk * QK_K) : NULL;
|
| 5128 |
-
for (int sj = 0; sj < N_SUB; sj++) {
|
| 5129 |
-
gLs[sj] = output[blk].scales[sj] & 0xF;
|
| 5130 |
-
gLm[sj] = output[blk].scales[sj] >> 4;
|
| 5131 |
-
}
|
| 5132 |
-
hex_vesica_commit(block_x, wrow, &dm, &mm, gLs, gLm, L);
|
| 5133 |
-
for (int sj = 0; sj < N_SUB; sj++)
|
| 5134 |
-
output[blk].scales[sj] = gLs[sj] | (gLm[sj] << 4);
|
| 5135 |
-
output[blk].d = gguf_fp32_to_fp16(dm);
|
| 5136 |
-
output[blk].dmin = gguf_fp32_to_fp16(mm);
|
| 5137 |
-
memcpy(Ls_blk, gLs, 16);
|
| 5138 |
-
memcpy(Lm_blk, gLm, 16);
|
| 5139 |
-
}
|
| 5140 |
-
|
| 5141 |
-
/* ββ PHASE 4.7: CANDIDATE FLOOR ββ
|
| 5142 |
*
|
| 5143 |
-
* candidate_errors is
|
| 5144 |
-
*
|
| 5145 |
-
*
|
| 5146 |
-
*
|
| 5147 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5148 |
{
|
| 5149 |
float fin_err = 0.0f;
|
|
|
|
| 5150 |
for (int j = 0; j < N_SUB; j++) {
|
| 5151 |
float d_sub = dm * (float)(output[blk].scales[j] & 0xF);
|
| 5152 |
float m_sub = mm * (float)(output[blk].scales[j] >> 4);
|
|
@@ -5154,11 +4685,12 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 5154 |
int idx = 16 * j + k;
|
| 5155 |
float w = (imat_importance) ?
|
| 5156 |
imat_importance[blk * QK_K + idx] : 1.0f;
|
| 5157 |
-
|
| 5158 |
-
|
| 5159 |
-
fin_err +=
|
| 5160 |
}
|
| 5161 |
}
|
|
|
|
| 5162 |
|
| 5163 |
float g_best = candidate_errors[blk][0];
|
| 5164 |
int g_cand = 0;
|
|
@@ -5198,22 +4730,6 @@ static void quantize_tensor_q2k_hpc(const float *weights, int64_t n_elements,
|
|
| 5198 |
}
|
| 5199 |
}
|
| 5200 |
|
| 5201 |
-
if (HEX_VW_LAMBDA != 0.0f || HEX_DC_LAMBDA != 0.0f) {
|
| 5202 |
-
uint8_t gLs[16], gLm[16];
|
| 5203 |
-
const float *wrow = imat_importance
|
| 5204 |
-
? (imat_importance + blk * QK_K) : NULL;
|
| 5205 |
-
for (int sj = 0; sj < N_SUB; sj++) {
|
| 5206 |
-
gLs[sj] = output[blk].scales[sj] & 0xF;
|
| 5207 |
-
gLm[sj] = output[blk].scales[sj] >> 4;
|
| 5208 |
-
}
|
| 5209 |
-
float sse_pre = hex_block_sse(block_x, wrow, dm, mm, gLs, gLm, L);
|
| 5210 |
-
uint8_t Lpre[QK_K];
|
| 5211 |
-
memcpy(Lpre, L, QK_K);
|
| 5212 |
-
hex_vesica_guide_pairs(block_x, wrow, dm, mm, gLs, gLm, L);
|
| 5213 |
-
if (hex_block_sse(block_x, wrow, dm, mm, gLs, gLm, L) > sse_pre)
|
| 5214 |
-
memcpy(L, Lpre, QK_K);
|
| 5215 |
-
}
|
| 5216 |
-
|
| 5217 |
for (int j = 0; j < QK_K; j += 128) {
|
| 5218 |
for (int l = 0; l < 32; l++) {
|
| 5219 |
output[blk].qs[j / 4 + l] = L[j + l]
|
|
|
|
| 1761 |
*
|
| 1762 |
* E(block) = Ξ£α΅’ wα΅’eα΅’Β²
|
| 1763 |
* + (HEX_DC_LAMBDA / n) Β· (Ξ£α΅’eα΅’)Β²
|
| 1764 |
+
* + (HEX_VW_LAMBDA / n) Β· Ξ£_{i<n/2} (eα΅’+eβ±Ό)Β², j = i+n/2
|
| 1765 |
*
|
| 1766 |
+
* Pair vesica v = eα΅’+eβ±Ό is the DC of that fold pair; block DC is Ξ£ v.
|
| 1767 |
+
* Penalising Ξ£ vΒ² (not vΒ²βwΒ²) lowers both |DC| and mean vesica. The old
|
| 1768 |
+
* 4 eα΅’eβ±Ό = vΒ²βwΒ² wave-credit paid for anti-phase amplitude and could
|
| 1769 |
+
* raise vesica while looking like a win. Ξ» = 0 on both knobs is pure SSE.
|
| 1770 |
+
* NOTE: reported RMSE stays reconstruction RMSE.
|
| 1771 |
+
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1772 |
#ifndef HEX_DC_LAMBDA_DEFAULT
|
| 1773 |
+
#define HEX_DC_LAMBDA_DEFAULT 1.0f
|
| 1774 |
#endif
|
| 1775 |
#ifndef HEX_VW_LAMBDA_DEFAULT
|
| 1776 |
+
#define HEX_VW_LAMBDA_DEFAULT 1.0f
|
| 1777 |
#endif
|
| 1778 |
#ifndef HEX_DC_DECAY_DEFAULT
|
| 1779 |
+
#define HEX_DC_DECAY_DEFAULT 0.85f
|
| 1780 |
#endif
|
| 1781 |
+
|
| 1782 |
+
static float g_hex_dc_lambda = HEX_DC_LAMBDA_DEFAULT;
|
| 1783 |
+
static float g_hex_vw_lambda = HEX_VW_LAMBDA_DEFAULT;
|
| 1784 |
+
static float g_hex_dc_decay = HEX_DC_DECAY_DEFAULT;
|
| 1785 |
+
#define HEX_DC_LAMBDA (g_hex_dc_lambda)
|
| 1786 |
+
#define HEX_VW_LAMBDA (g_hex_vw_lambda)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1787 |
|
| 1788 |
void hexstate_set_spectral_params(float dc_lambda, float vw_lambda, float dc_decay)
|
| 1789 |
{
|
| 1790 |
+
g_hex_dc_lambda = dc_lambda;
|
| 1791 |
+
g_hex_vw_lambda = vw_lambda;
|
| 1792 |
if (dc_decay >= 0.0f && dc_decay <= 1.0f)
|
| 1793 |
+
g_hex_dc_decay = dc_decay;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1794 |
}
|
| 1795 |
|
| 1796 |
+
/* Spectral penalty: DCΒ² + Ξ£ vesicaΒ². Always β₯ 0 (no wave credit). */
|
| 1797 |
static inline float hex_spectral_penalty(const float *e, int n)
|
| 1798 |
{
|
| 1799 |
if (HEX_DC_LAMBDA == 0.0f && HEX_VW_LAMBDA == 0.0f) return 0.0f;
|
|
|
|
| 1804 |
dc += v;
|
| 1805 |
ves += v * v;
|
| 1806 |
}
|
| 1807 |
+
return (HEX_DC_LAMBDA / (float)n) * dc * dc
|
| 1808 |
+
+ (HEX_VW_LAMBDA / (float)n) * ves;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1809 |
}
|
| 1810 |
|
| 1811 |
/* Robust temperature estimator for the HExState measurement model.
|
|
|
|
| 2442 |
}
|
| 2443 |
|
| 2444 |
float v_live[QK4_0 / 2];
|
| 2445 |
+
float vesica_cur = 0.0f, dc_cur = 0.0f;
|
| 2446 |
for (int j = 0; j < QK4_0 / 2; j++) {
|
| 2447 |
v_live[j] = e_live[j] + e_live[j + QK4_0 / 2];
|
| 2448 |
vesica_cur += v_live[j] * v_live[j];
|
|
|
|
| 2449 |
}
|
| 2450 |
for (int j = 0; j < QK4_0; j++) dc_cur += e_live[j];
|
| 2451 |
+
float metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
| 2452 |
|
| 2453 |
/* Deterministic greedy descent: only strict improvements.
|
| 2454 |
* The previous SA acceptance called rand() inside an OpenMP
|
|
|
|
| 2478 |
|
| 2479 |
float vesica_alt = vesica_cur - v_old * v_old + v_new * v_new;
|
| 2480 |
float dc_alt = dc_cur + de;
|
| 2481 |
+
float metric_alt = 4.0f * vesica_alt + dc_alt * dc_alt;
|
| 2482 |
|
| 2483 |
float delta = metric_cur - metric_alt;
|
| 2484 |
if (delta > best_delta) {
|
|
|
|
| 2502 |
|
| 2503 |
vesica_cur += v_new_commit * v_new_commit - v_old_commit * v_old_commit;
|
| 2504 |
dc_cur += de_commit;
|
| 2505 |
+
metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
| 2506 |
|
| 2507 |
v_live[pi_commit] = v_new_commit;
|
| 2508 |
e_live[best_k] = e_new_commit;
|
|
|
|
| 2813 |
int8_t qs_shaped[QK8_0];
|
| 2814 |
memcpy(qs_shaped, qs, QK8_0);
|
| 2815 |
float e_live[QK8_0], v_live[QK8_0 / 2];
|
| 2816 |
+
float vesica_cur = 0.0f, dc_cur = 0.0f;
|
| 2817 |
for (int k = 0; k < QK8_0; k++)
|
| 2818 |
e_live[k] = bw[k] - (float)qs_shaped[k] * d;
|
| 2819 |
for (int p = 0; p < QK8_0 / 2; p++) {
|
| 2820 |
v_live[p] = e_live[p] + e_live[p + QK8_0 / 2];
|
| 2821 |
vesica_cur += v_live[p] * v_live[p];
|
|
|
|
| 2822 |
dc_cur += v_live[p];
|
| 2823 |
}
|
| 2824 |
+
float metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
| 2825 |
for (int pass = 0; pass < QK8_0; pass++) {
|
| 2826 |
int best_k = -1, best_q_alt = 0;
|
| 2827 |
float best_delta = 0.0f;
|
|
|
|
| 2836 |
float ves_a = vesica_cur - v_live[pi] * v_live[pi]
|
| 2837 |
+ v_new * v_new;
|
| 2838 |
float dc_a = dc_cur + de;
|
| 2839 |
+
float delta = metric_cur - (4.0f * ves_a + dc_a * dc_a);
|
|
|
|
| 2840 |
if (delta > best_delta) {
|
| 2841 |
best_delta = delta; best_k = k; best_q_alt = q_try;
|
| 2842 |
}
|
|
|
|
| 2850 |
float v_new = v_live[pi] + de;
|
| 2851 |
vesica_cur += v_new * v_new - v_live[pi] * v_live[pi];
|
| 2852 |
dc_cur += de;
|
| 2853 |
+
metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
| 2854 |
v_live[pi] = v_new;
|
| 2855 |
e_live[best_k] = e_new;
|
| 2856 |
qs_shaped[best_k] = (int8_t)best_q_alt;
|
|
|
|
| 3635 |
* this array (safe: written sequentially before the parallel loop).
|
| 3636 |
* ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 3637 |
|
| 3638 |
+
#define DC_DECAY (g_hex_dc_decay)
|
| 3639 |
+
|
| 3640 |
float *block_dc_bias = (float *)calloc(n_blocks, sizeof(float));
|
| 3641 |
|
| 3642 |
if (block_dc_bias) {
|
|
|
|
| 3665 |
dm0, mm0, dc_Ls, dc_Lm);
|
| 3666 |
|
| 3667 |
/* Bias applied to THIS block's WLS targets */
|
| 3668 |
+
float dc_bias = (DC_DECAY * rolling_dc) / (float)QK_K;
|
| 3669 |
block_dc_bias[blk] = dc_bias;
|
| 3670 |
|
| 3671 |
/* Quick round-nearest quant to estimate DC residual for NEXT block.
|
|
|
|
| 3737 |
uint16_t prev_dm16 = 0, prev_mm16 = 0;
|
| 3738 |
for (int ls_iter = 0; ls_iter < 5; ls_iter++) {
|
| 3739 |
|
|
|
|
| 3740 |
uint8_t state_ls[N_SUB][6];
|
| 3741 |
uint8_t state_lm[N_SUB][6];
|
| 3742 |
float state_err[N_SUB][6];
|
|
|
|
| 3819 |
|
| 3820 |
for (int j = 0; j < N_SUB - 1; j++)
|
| 3821 |
hpc_cz(sg, j, j + 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3822 |
|
| 3823 |
double sub_marg[N_SUB][6];
|
| 3824 |
int sub_measured[N_SUB];
|
|
|
|
| 3827 |
|
| 3828 |
sieve_measure_graph(sg, N_SUB, sub_marg, sub_measured, 1);
|
| 3829 |
|
| 3830 |
+
for (int j = 0; j < N_SUB; j++) {
|
| 3831 |
+
double best_prob = -1.0;
|
| 3832 |
+
int best_v = 0;
|
| 3833 |
+
for (int v = 0; v < 6; v++) {
|
| 3834 |
+
if (sub_marg[j][v] > best_prob) {
|
| 3835 |
+
best_prob = sub_marg[j][v];
|
| 3836 |
+
best_v = v;
|
| 3837 |
+
}
|
| 3838 |
+
}
|
| 3839 |
+
Ls_blk[j] = state_ls[j][best_v];
|
| 3840 |
+
Lm_blk[j] = state_lm[j][best_v];
|
| 3841 |
+
}
|
| 3842 |
+
}
|
| 3843 |
+
|
| 3844 |
+
uint8_t L[QK_K];
|
| 3845 |
+
for (int j = 0; j < N_SUB; j++) {
|
| 3846 |
+
float d_sub = dm * (float)Ls_blk[j];
|
| 3847 |
+
float m_sub = mm * (float)Lm_blk[j];
|
| 3848 |
+
if (d_sub < 1e-15f) {
|
| 3849 |
+
for (int k = 0; k < 16; k++) L[16*j+k] = 0;
|
| 3850 |
+
continue;
|
| 3851 |
+
}
|
| 3852 |
+
for (int k = 0; k < 16; k++) {
|
| 3853 |
+
int q = gguf_nearest_int((adj_block_x[16*j+k] + m_sub) / d_sub);
|
| 3854 |
+
if (q < 0) q = 0; if (q > 3) q = 3;
|
| 3855 |
+
L[16*j+k] = (uint8_t)q;
|
| 3856 |
+
}
|
| 3857 |
}
|
| 3858 |
|
| 3859 |
double Saa = 0, Sab = 0, Sbb = 0, Sxa = 0, Sxb = 0;
|
|
|
|
| 3917 |
float d_sub = trial_dm * (float)Ls_blk[j];
|
| 3918 |
float m_sub = trial_mm * (float)Lm_blk[j];
|
| 3919 |
for (int k = 0; k < 16; k++) {
|
| 3920 |
+
float x = adj_block_x[16*j+k];
|
| 3921 |
float w = (imat_importance) ?
|
| 3922 |
imat_importance[blk * QK_K + 16*j+k] : 1.0f;
|
| 3923 |
int q;
|
|
|
|
| 3943 |
}
|
| 3944 |
|
| 3945 |
for (int j = 0; j < N_SUB; j++) {
|
| 3946 |
+
const float *sx = adj_block_x + 16 * j;
|
| 3947 |
float best_sub_err = 1e30f;
|
| 3948 |
uint8_t best_ls = Ls_blk[j], best_lm = Lm_blk[j];
|
| 3949 |
for (int try_ls = 0; try_ls <= 15; try_ls++) {
|
|
|
|
| 3998 |
*/
|
| 3999 |
uint8_t L[QK_K];
|
| 4000 |
{
|
| 4001 |
+
float q_cont_all[QK_K];
|
| 4002 |
+
int q_base_all[QK_K];
|
| 4003 |
+
int q_shaped_all[QK_K];
|
| 4004 |
+
|
| 4005 |
+
for (int i = 0; i < QK_K; i++) {
|
| 4006 |
+
int jj = i >> 4;
|
| 4007 |
+
float d_s = dm * (float)(output[blk].scales[jj] & 0xF);
|
| 4008 |
+
float m_s = mm * (float)(output[blk].scales[jj] >> 4);
|
| 4009 |
+
if (d_s < 1e-15f) {
|
| 4010 |
+
q_cont_all[i] = 0.0f;
|
| 4011 |
+
q_base_all[i] = 0;
|
| 4012 |
+
} else {
|
| 4013 |
+
/* Quantize the DC-adjusted target */
|
| 4014 |
+
float qc = (adj_block_x[i] + m_s) / d_s;
|
| 4015 |
+
q_cont_all[i] = qc;
|
| 4016 |
+
int qr = gguf_nearest_int(qc);
|
| 4017 |
+
if (qr < 0) qr = 0; if (qr > 3) qr = 3;
|
| 4018 |
+
q_base_all[i] = qr;
|
| 4019 |
+
}
|
| 4020 |
+
}
|
| 4021 |
memcpy(q_shaped_all, q_base_all, QK_K * sizeof(int));
|
| 4022 |
|
| 4023 |
float e_live[QK_K];
|
| 4024 |
+
float dc_cur = 0.0f;
|
| 4025 |
for (int i = 0; i < QK_K; i++) {
|
| 4026 |
int jj = i >> 4;
|
| 4027 |
float d_s = dm * (float)(output[blk].scales[jj] & 0xF);
|
| 4028 |
float m_s = mm * (float)(output[blk].scales[jj] >> 4);
|
|
|
|
|
|
|
| 4029 |
float deq = d_s * (float)q_shaped_all[i] - m_s;
|
| 4030 |
+
/* Vesica on ORIGINAL residuals. DC on the rolling-adjusted
|
| 4031 |
+
* residual so this block still absorbs Phase 3.9's target. */
|
| 4032 |
e_live[i] = block_x[i] - deq;
|
| 4033 |
+
dc_cur += adj_block_x[i] - deq;
|
| 4034 |
}
|
| 4035 |
|
| 4036 |
float v_live[QK_K / 2];
|
| 4037 |
+
float vesica_cur = 0.0f;
|
| 4038 |
for (int i = 0; i < QK_K / 2; i++) {
|
| 4039 |
v_live[i] = e_live[i] + e_live[i + QK_K / 2];
|
| 4040 |
vesica_cur += v_live[i] * v_live[i];
|
|
|
|
| 4041 |
}
|
| 4042 |
+
float metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4043 |
|
| 4044 |
+
/* Deterministic greedy descent: accept only strict improvements */
|
| 4045 |
for (int pass = 0; pass < QK_K; pass++) {
|
| 4046 |
int best_k = -1;
|
| 4047 |
int best_q_alt = 0;
|
|
|
|
| 4055 |
int q_cur = q_shaped_all[k];
|
| 4056 |
float m_s = mm * (float)(output[blk].scales[jj] >> 4);
|
| 4057 |
int pi = (k < QK_K / 2) ? k : k - QK_K / 2;
|
|
|
|
| 4058 |
|
| 4059 |
+
/* Try ALL alternate codes, not just Β±1. A weight at q=0
|
| 4060 |
+
* with strong positive DC bias may need to jump to q=2 or
|
| 4061 |
+
* q=3; the old Β±1 path took multiple passes to walk there
|
| 4062 |
+
* one step at a time, if it got there at all. */
|
| 4063 |
for (int q_try = 0; q_try <= 3; q_try++) {
|
| 4064 |
if (q_try == q_cur) continue;
|
| 4065 |
|
|
|
|
| 4070 |
|
| 4071 |
float vesica_alt = vesica_cur - v_live[pi]*v_live[pi] + v_new*v_new;
|
| 4072 |
float dc_alt = dc_cur + de;
|
| 4073 |
+
float delta = metric_cur - (4.0f * vesica_alt + dc_alt * dc_alt);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4074 |
|
| 4075 |
if (delta > best_delta) {
|
| 4076 |
best_delta = delta;
|
|
|
|
| 4091 |
float de_c = e_new_c - e_live[best_k];
|
| 4092 |
int pi_c = (best_k < QK_K / 2) ? best_k : best_k - QK_K / 2;
|
| 4093 |
float v_new_c = v_live[pi_c] + de_c;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4094 |
vesica_cur += v_new_c * v_new_c - v_live[pi_c] * v_live[pi_c];
|
| 4095 |
dc_cur += de_c;
|
| 4096 |
+
metric_cur = 4.0f * vesica_cur + dc_cur * dc_cur;
|
|
|
|
| 4097 |
v_live[pi_c] = v_new_c;
|
| 4098 |
e_live[best_k]= e_new_c;
|
| 4099 |
}
|
|
|
|
| 4438 |
int pi = j & 7; /* fold-pair index */
|
| 4439 |
int pj = j ^ 8; /* partner sub-block */
|
| 4440 |
const float *ppe = pe + 16 * pj; /* partner residuals */
|
| 4441 |
+
float dc_rest = dc_tot - sub_dc[j];
|
| 4442 |
+
float ves_rest = ves_tot - pair_ves[pi];
|
| 4443 |
|
| 4444 |
/* Extended score of the CURRENT committed state */
|
| 4445 |
float best_sub = sub_sse[j]
|
|
|
|
| 4448 |
int best_ls = -1, best_lm = 0;
|
| 4449 |
uint8_t best_q[16];
|
| 4450 |
float best_e[16];
|
| 4451 |
+
float best_sse = 0.0f, best_dcc = 0.0f, best_ves = 0.0f;
|
| 4452 |
|
| 4453 |
for (int try_ls = 0; try_ls <= 15; try_ls++) {
|
| 4454 |
float d_sub = dm * (float)try_ls;
|
| 4455 |
for (int try_lm = 0; try_lm <= 15; try_lm++) {
|
| 4456 |
float m_sub = mm * (float)try_lm;
|
| 4457 |
+
float sub_err = 0.0f, dcc = 0.0f, vesc = 0.0f;
|
| 4458 |
uint8_t q_loc[16];
|
| 4459 |
float e_loc[16];
|
| 4460 |
int aborted = 0;
|
|
|
|
| 4468 |
if (q < 0) q = 0; if (q > 3) q = 3;
|
| 4469 |
}
|
| 4470 |
q_loc[k] = (uint8_t)q;
|
|
|
|
| 4471 |
float e = x - (d_sub * (float)q - m_sub);
|
| 4472 |
e_loc[k] = e;
|
| 4473 |
sub_err += e * e * w;
|
| 4474 |
dcc += e;
|
| 4475 |
{
|
| 4476 |
+
float v = e + ppe[k];
|
| 4477 |
+
vesc += v * v;
|
| 4478 |
}
|
| 4479 |
+
/* Spectral terms are β₯ 0, so SSE is a valid prune. */
|
| 4480 |
+
if (sub_err >= best_sub) { aborted = 1; break; }
|
| 4481 |
}
|
| 4482 |
if (aborted) continue;
|
| 4483 |
float score = sub_err
|
| 4484 |
+ (HEX_DC_LAMBDA / (float)QK_K)
|
| 4485 |
* (dc_rest + dcc) * (dc_rest + dcc)
|
| 4486 |
+ (HEX_VW_LAMBDA / (float)QK_K)
|
| 4487 |
+
* (ves_rest + vesc);
|
| 4488 |
if (score < best_sub) {
|
| 4489 |
best_sub = score;
|
| 4490 |
best_ls = try_ls;
|
|
|
|
| 4493 |
memcpy(best_e, e_loc, sizeof(e_loc));
|
| 4494 |
best_sse = sub_err;
|
| 4495 |
best_dcc = dcc;
|
| 4496 |
+
best_ves = vesc;
|
| 4497 |
}
|
| 4498 |
}
|
| 4499 |
}
|
|
|
|
| 4503 |
pl_Lm[j] = (uint8_t)best_lm;
|
| 4504 |
memcpy(L + 16 * j, best_q, 16);
|
| 4505 |
memcpy(pe + 16 * j, best_e, sizeof(best_e));
|
| 4506 |
+
sub_sse[j] = best_sse;
|
| 4507 |
+
sub_dc[j] = best_dcc;
|
| 4508 |
+
pair_ves[pi] = best_ves;
|
| 4509 |
+
dc_tot = dc_rest + best_dcc;
|
| 4510 |
+
ves_tot = ves_rest + best_ves;
|
| 4511 |
pol_improved = 1;
|
| 4512 |
}
|
| 4513 |
}
|
|
|
|
| 4624 |
float t_mm = gguf_fp16_to_fp32((uint16_t)cm16);
|
| 4625 |
|
| 4626 |
float err = 0.0f;
|
| 4627 |
+
int pruned = 0;
|
| 4628 |
+
for (int j = 0; j < N_SUB; j++) {
|
|
|
|
|
|
|
|
|
|
| 4629 |
float d_sub = t_dm * (float)pl_Ls[j];
|
| 4630 |
float m_sub = t_mm * (float)pl_Lm[j];
|
| 4631 |
for (int k = 0; k < 16; k++) {
|
|
|
|
| 4636 |
(d_sub * (float)L[idx] - m_sub);
|
| 4637 |
err += e_u[idx] * e_u[idx] * w;
|
| 4638 |
}
|
| 4639 |
+
if (err >= best_err) { pruned = 1; break; }
|
| 4640 |
}
|
| 4641 |
+
if (pruned) continue;
|
| 4642 |
+
err += hex_spectral_penalty(e_u, QK_K);
|
|
|
|
|
|
|
| 4643 |
if (err < best_err) {
|
| 4644 |
best_err = err;
|
| 4645 |
best_d16 = (uint16_t)cd16;
|
|
|
|
| 4664 |
output[blk].dmin = gguf_fp32_to_fp16(mm);
|
| 4665 |
}
|
| 4666 |
|
| 4667 |
+
/* ββ PHASE 4.7: CANDIDATE FLOOR (worst-case bound) ββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4668 |
*
|
| 4669 |
+
* candidate_errors[blk][c] is the EXACT weighted SSE of a directly
|
| 4670 |
+
* encodable configuration (fp16 d/dmin + derived Ls/Lm + nearest
|
| 4671 |
+
* rounding vs the original weights). The multi-stage assembly
|
| 4672 |
+
* (DC-shifted WLS, shaping, diffusion, polish) usually improves on
|
| 4673 |
+
* its seed, but each stage optimises a slightly different objective
|
| 4674 |
+
* and coordinate descent can land in a worse basin. Compare the
|
| 4675 |
+
* finished block against the best raw candidate and fall back when
|
| 4676 |
+
* the pipeline ended up worse β guaranteeing
|
| 4677 |
+
* final weighted SSE β€ min_c candidate_errors[blk][c]. */
|
| 4678 |
{
|
| 4679 |
float fin_err = 0.0f;
|
| 4680 |
+
float e_f[QK_K];
|
| 4681 |
for (int j = 0; j < N_SUB; j++) {
|
| 4682 |
float d_sub = dm * (float)(output[blk].scales[j] & 0xF);
|
| 4683 |
float m_sub = mm * (float)(output[blk].scales[j] >> 4);
|
|
|
|
| 4685 |
int idx = 16 * j + k;
|
| 4686 |
float w = (imat_importance) ?
|
| 4687 |
imat_importance[blk * QK_K + idx] : 1.0f;
|
| 4688 |
+
e_f[idx] = block_x[idx] -
|
| 4689 |
+
(d_sub * (float)L[idx] - m_sub);
|
| 4690 |
+
fin_err += e_f[idx] * e_f[idx] * w;
|
| 4691 |
}
|
| 4692 |
}
|
| 4693 |
+
fin_err += hex_spectral_penalty(e_f, QK_K);
|
| 4694 |
|
| 4695 |
float g_best = candidate_errors[blk][0];
|
| 4696 |
int g_cand = 0;
|
|
|
|
| 4730 |
}
|
| 4731 |
}
|
| 4732 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4733 |
for (int j = 0; j < QK_K; j += 128) {
|
| 4734 |
for (int l = 0; l < 32; l++) {
|
| 4735 |
output[blk].qs[j / 4 + l] = L[j + l]
|
hexstate_requantize.py
CHANGED
|
@@ -3,11 +3,9 @@
|
|
| 3 |
HexState GGUF Re-Quantizer β GGUF-to-GGUF Q2_K quantization.
|
| 4 |
|
| 5 |
Reads a source GGUF (F16/BF16/F32), copies all metadata verbatim,
|
| 6 |
-
and re-quantizes eligible weight tensors to Q2_K.
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
order is decode order, no sidecar. Pass --no-fold-interleave for
|
| 10 |
-
identity-layout Q2_K. Optional --fold-basis is a shared dimension perm.
|
| 11 |
|
| 12 |
This bypasses the tokenizer parsing problem entirely β the source GGUF
|
| 13 |
(from llama.cpp's convert_hf_to_gguf.py) has correct metadata.
|
|
@@ -22,7 +20,6 @@ import time
|
|
| 22 |
import os
|
| 23 |
import io
|
| 24 |
import ctypes
|
| 25 |
-
import re as _re
|
| 26 |
import numpy as np
|
| 27 |
|
| 28 |
# βββ HExState C Library (HPC-optimized Q2_K quantization) ββββββββββββββββββ
|
|
@@ -116,19 +113,9 @@ def _load_hexstate_lib():
|
|
| 116 |
if hasattr(lib, 'hexstate_set_spectral_params'):
|
| 117 |
lib.hexstate_set_spectral_params.restype = None
|
| 118 |
lib.hexstate_set_spectral_params.argtypes = [
|
| 119 |
-
ctypes.c_float, ctypes.c_float, ctypes.c_float
|
| 120 |
-
]
|
| 121 |
|
| 122 |
lib.hexstate_init()
|
| 123 |
-
dc_l = os.environ.get('HEX_DC_LAMBDA')
|
| 124 |
-
vw_l = os.environ.get('HEX_VW_LAMBDA')
|
| 125 |
-
dc_d = os.environ.get('HEX_DC_DECAY')
|
| 126 |
-
if hasattr(lib, 'hexstate_set_spectral_params') and (dc_l or vw_l or dc_d):
|
| 127 |
-
lib.hexstate_set_spectral_params(
|
| 128 |
-
ctypes.c_float(float(dc_l) if dc_l else 4.0),
|
| 129 |
-
ctypes.c_float(float(vw_l) if vw_l else 4.0),
|
| 130 |
-
ctypes.c_float(float(dc_d) if dc_d else 1.0),
|
| 131 |
-
)
|
| 132 |
_HEXSTATE_LIB = lib
|
| 133 |
return lib
|
| 134 |
except Exception as e:
|
|
@@ -317,7 +304,6 @@ GGML_TYPE_F16 = 1
|
|
| 317 |
GGML_TYPE_Q4_0 = 2
|
| 318 |
GGML_TYPE_Q8_0 = 8
|
| 319 |
GGML_TYPE_Q2_K = 10
|
| 320 |
-
GGML_TYPE_I16 = 25
|
| 321 |
GGML_TYPE_BF16 = 30
|
| 322 |
|
| 323 |
TYPE_NAME = {
|
|
@@ -330,12 +316,12 @@ TYPE_NAME = {
|
|
| 330 |
TYPE_BLOCK_SIZE = {
|
| 331 |
0: 1, 1: 1, 2: 32, 3: 32, 6: 32, 7: 32,
|
| 332 |
8: 32, 9: 32, 10: 256, 11: 256, 12: 256,
|
| 333 |
-
13: 256, 14: 256, 15: 256,
|
| 334 |
}
|
| 335 |
TYPE_BLOCK_BYTES = {
|
| 336 |
0: 4, 1: 2, 2: 18, 3: 20, 6: 20, 7: 22,
|
| 337 |
8: 34, 9: 36, 10: 84, 11: 110, 12: 144,
|
| 338 |
-
13: 176, 14: 210, 15: 292,
|
| 339 |
}
|
| 340 |
|
| 341 |
|
|
@@ -411,540 +397,6 @@ def f32_to_bf16(f32_array):
|
|
| 411 |
return bf16.tobytes()
|
| 412 |
|
| 413 |
|
| 414 |
-
def _src_to_f32(raw_data, ti):
|
| 415 |
-
if ti['type'] == GGML_TYPE_BF16:
|
| 416 |
-
return bf16_to_f32(raw_data, ti['n_elements'])
|
| 417 |
-
if ti['type'] == GGML_TYPE_F16:
|
| 418 |
-
return f16_to_f32(raw_data, ti['n_elements'])
|
| 419 |
-
if ti['type'] == GGML_TYPE_F32:
|
| 420 |
-
return np.frombuffer(raw_data, dtype=np.float32).copy()
|
| 421 |
-
return None
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
def _f32_to_src_bytes(f32, ttype):
|
| 425 |
-
if ttype == GGML_TYPE_F32:
|
| 426 |
-
return np.ascontiguousarray(f32, dtype=np.float32).tobytes()
|
| 427 |
-
if ttype == GGML_TYPE_F16:
|
| 428 |
-
return f32_to_f16(f32)
|
| 429 |
-
if ttype == GGML_TYPE_BF16:
|
| 430 |
-
return f32_to_bf16(np.ascontiguousarray(f32, dtype=np.float32))
|
| 431 |
-
return None
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
# βββ Fold-basis (stock-llama equivalent network) ββββββββββββββββββββββββββ
|
| 435 |
-
# One permutation of the hidden dim + one per-layer permutation of the
|
| 436 |
-
# FFN intermediate dim. Applied to every tensor that touches that axis
|
| 437 |
-
# (weights, embeddings, norms) so W'x' = Wx. Ordinary Q2_K GGUF; llama.cpp
|
| 438 |
-
# loads it as the same model in a rotated basis.
|
| 439 |
-
#
|
| 440 |
-
# Column statistics, not per-block argsort: a data-dependent shuffle
|
| 441 |
-
# inside each 256-block would be a valid Q2_K file that llama cannot
|
| 442 |
-
# matmul correctly.
|
| 443 |
-
|
| 444 |
-
def _fb_tensor_perms(name):
|
| 445 |
-
"""Return list of (perm_key, axis) for this tensor.
|
| 446 |
-
axis: 0 β permute dims[0] (columns/input, what blocks span)
|
| 447 |
-
1 β permute dims[1] (rows/output)
|
| 448 |
-
'1d' β 1D parameter (norms)
|
| 449 |
-
"""
|
| 450 |
-
perms = []
|
| 451 |
-
if _re.match(r'blk\.\d+\.attn_(q|k|v|qkv)\.weight', name) or \
|
| 452 |
-
_re.match(r'blk\.\d+\.attn_gate\.weight', name) or \
|
| 453 |
-
_re.match(r'blk\.\d+\.ssm_(in_qkv|in_z|in_x|out)\.weight', name) or \
|
| 454 |
-
_re.match(r'blk\.\d+\.ffn_(gate|up)\.weight', name) or \
|
| 455 |
-
name in ('token_embd.weight', 'output.weight'):
|
| 456 |
-
perms.append(('hidden', 0))
|
| 457 |
-
# Square hiddenβhidden maps need Pα΅WP. Mismatched axis is a no-op.
|
| 458 |
-
if _re.match(r'blk\.\d+\.(attn_gate|ssm_out)\.weight', name):
|
| 459 |
-
perms.append(('hidden', 1))
|
| 460 |
-
if _re.match(r'blk\.\d+\.attn_output\.weight', name) or \
|
| 461 |
-
_re.match(r'blk\.\d+\.ffn_down\.weight', name):
|
| 462 |
-
perms.append(('hidden', 1))
|
| 463 |
-
if _re.match(r'blk\.\d+\.(attn|ffn)_norm\.weight', name) or \
|
| 464 |
-
name == 'output_norm.weight':
|
| 465 |
-
perms.append(('hidden', '1d'))
|
| 466 |
-
m = _re.match(r'blk\.(\d+)\.ffn_down\.weight', name)
|
| 467 |
-
if m:
|
| 468 |
-
perms.append((f'inter_{m.group(1)}', 0))
|
| 469 |
-
m = _re.match(r'blk\.(\d+)\.ffn_(gate|up)\.weight', name)
|
| 470 |
-
if m:
|
| 471 |
-
perms.append((f'inter_{m.group(1)}', 1))
|
| 472 |
-
return perms
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
def _fb_compute_perm(energies, block_size=QK_K):
|
| 476 |
-
"""Stride-interleave: pair low-energy with high-energy columns at
|
| 477 |
-
fold-complementary positions, dealt across QK_K blocks."""
|
| 478 |
-
dim = len(energies)
|
| 479 |
-
n_blocks = dim // block_size
|
| 480 |
-
half = block_size // 2
|
| 481 |
-
remainder = dim % block_size
|
| 482 |
-
|
| 483 |
-
if n_blocks == 0 or remainder != 0:
|
| 484 |
-
return np.arange(dim, dtype=np.intp)
|
| 485 |
-
|
| 486 |
-
sorted_idx = np.argsort(energies)
|
| 487 |
-
low = sorted_idx[:dim // 2]
|
| 488 |
-
high = sorted_idx[dim // 2:][::-1]
|
| 489 |
-
|
| 490 |
-
low_blocks = low.reshape(half, n_blocks).T
|
| 491 |
-
high_blocks = high.reshape(half, n_blocks).T
|
| 492 |
-
|
| 493 |
-
perm = np.empty(dim, dtype=np.intp)
|
| 494 |
-
for b in range(n_blocks):
|
| 495 |
-
s = b * block_size
|
| 496 |
-
perm[s:s + half] = low_blocks[b]
|
| 497 |
-
perm[s + half:s + block_size] = high_blocks[b]
|
| 498 |
-
return perm
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
def _fb_apply(f32, dims, perm, axis):
|
| 502 |
-
if axis == '1d':
|
| 503 |
-
if len(perm) != len(f32):
|
| 504 |
-
return f32
|
| 505 |
-
return f32[perm].copy()
|
| 506 |
-
d0 = int(dims[0])
|
| 507 |
-
d1 = int(dims[1]) if len(dims) > 1 else 1
|
| 508 |
-
if axis == 0 and len(perm) != d0:
|
| 509 |
-
return f32
|
| 510 |
-
if axis == 1 and len(perm) != d1:
|
| 511 |
-
return f32
|
| 512 |
-
M = f32.reshape(d1, d0)
|
| 513 |
-
if axis == 0:
|
| 514 |
-
M = M[:, perm]
|
| 515 |
-
else:
|
| 516 |
-
M = M[perm, :]
|
| 517 |
-
return M.reshape(-1).copy()
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
def _fb_apply_tensor(f32, ti, fb_perms, imat_full=None):
|
| 521 |
-
if not fb_perms:
|
| 522 |
-
return f32, imat_full
|
| 523 |
-
for key, axis in _fb_tensor_perms(ti['name']):
|
| 524 |
-
perm = fb_perms.get(key)
|
| 525 |
-
if perm is None:
|
| 526 |
-
continue
|
| 527 |
-
f32 = _fb_apply(f32, ti['dims'], perm, axis)
|
| 528 |
-
if imat_full is not None:
|
| 529 |
-
if imat_full.size == f32.size:
|
| 530 |
-
imat_full = _fb_apply(imat_full, ti['dims'], perm, axis)
|
| 531 |
-
elif imat_full.size == len(perm) and axis in (0, '1d'):
|
| 532 |
-
imat_full = imat_full[perm].copy()
|
| 533 |
-
return f32, imat_full
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
def _chunk_max_elems():
|
| 537 |
-
"""Peak f32 elements per tensor chunk. Override with HEX_CHUNK_ELEMS."""
|
| 538 |
-
raw = os.environ.get('HEX_CHUNK_ELEMS', '2000000')
|
| 539 |
-
try:
|
| 540 |
-
n = int(raw)
|
| 541 |
-
except ValueError:
|
| 542 |
-
n = 2_000_000
|
| 543 |
-
return max(QK_K, n)
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
def _elem_nbytes(ttype):
|
| 547 |
-
if ttype == GGML_TYPE_F32:
|
| 548 |
-
return 4
|
| 549 |
-
if ttype in (GGML_TYPE_F16, GGML_TYPE_BF16):
|
| 550 |
-
return 2
|
| 551 |
-
return None
|
| 552 |
-
|
| 553 |
-
|
| 554 |
-
def _bytes_to_f32(raw, ttype, n_elements):
|
| 555 |
-
if ttype == GGML_TYPE_F32:
|
| 556 |
-
return np.frombuffer(raw, dtype=np.float32).copy()
|
| 557 |
-
if ttype == GGML_TYPE_F16:
|
| 558 |
-
return f16_to_f32(raw, n_elements)
|
| 559 |
-
if ttype == GGML_TYPE_BF16:
|
| 560 |
-
return bf16_to_f32(raw, n_elements)
|
| 561 |
-
return None
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
def _fb_axis_maps(ti, fb_perms):
|
| 565 |
-
"""Compose fold-basis into (row_perm, col_perm, is_1d)."""
|
| 566 |
-
if not fb_perms:
|
| 567 |
-
return None, None, False
|
| 568 |
-
row_perm = col_perm = vec_perm = None
|
| 569 |
-
for key, axis in _fb_tensor_perms(ti['name']):
|
| 570 |
-
perm = fb_perms.get(key)
|
| 571 |
-
if perm is None:
|
| 572 |
-
continue
|
| 573 |
-
if axis == '1d':
|
| 574 |
-
vec_perm = perm
|
| 575 |
-
elif axis == 0:
|
| 576 |
-
col_perm = perm
|
| 577 |
-
else:
|
| 578 |
-
row_perm = perm
|
| 579 |
-
if vec_perm is not None:
|
| 580 |
-
return vec_perm, None, True
|
| 581 |
-
return row_perm, col_perm, False
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
def _read_src_rows(fin, abs_offset, ttype, d0, src_rows):
|
| 585 |
-
"""Load selected source rows as float32 [n_rows, d0], coalescing runs."""
|
| 586 |
-
src_rows = np.asarray(src_rows, dtype=np.intp)
|
| 587 |
-
nbytes = _elem_nbytes(ttype)
|
| 588 |
-
if nbytes is None:
|
| 589 |
-
raise ValueError(f'cannot stream type {ttype}')
|
| 590 |
-
row_bytes = d0 * nbytes
|
| 591 |
-
n = int(src_rows.size)
|
| 592 |
-
out = np.empty((n, d0), dtype=np.float32)
|
| 593 |
-
i = 0
|
| 594 |
-
while i < n:
|
| 595 |
-
j = i + 1
|
| 596 |
-
while j < n and int(src_rows[j]) == int(src_rows[j - 1]) + 1:
|
| 597 |
-
j += 1
|
| 598 |
-
r0 = int(src_rows[i])
|
| 599 |
-
nr = j - i
|
| 600 |
-
fin.seek(abs_offset + r0 * row_bytes)
|
| 601 |
-
raw = fin.read(nr * row_bytes)
|
| 602 |
-
if len(raw) != nr * row_bytes:
|
| 603 |
-
raise IOError(f'short read at row {r0}: {len(raw)}/{nr * row_bytes}')
|
| 604 |
-
out[i:j] = _bytes_to_f32(raw, ttype, nr * d0).reshape(nr, d0)
|
| 605 |
-
i = j
|
| 606 |
-
return out
|
| 607 |
-
|
| 608 |
-
|
| 609 |
-
def _load_dest_chunk_f32(fin, abs_offset, ttype, d0, r0, r1, row_perm, col_perm):
|
| 610 |
-
dest = np.arange(r0, r1, dtype=np.intp)
|
| 611 |
-
src = row_perm[dest] if row_perm is not None else dest
|
| 612 |
-
M = _read_src_rows(fin, abs_offset, ttype, d0, src)
|
| 613 |
-
if col_perm is not None:
|
| 614 |
-
M = M[:, col_perm]
|
| 615 |
-
return np.ascontiguousarray(M.reshape(-1))
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
def _stream_col_mean(fin, data_section_start, ti):
|
| 619 |
-
"""Column mean of a 2D tensor without loading it whole."""
|
| 620 |
-
d0 = int(ti['dims'][0])
|
| 621 |
-
d1 = int(ti['dims'][1]) if ti['n_dims'] > 1 else 1
|
| 622 |
-
ttype = ti['type']
|
| 623 |
-
if _elem_nbytes(ttype) is None:
|
| 624 |
-
return None
|
| 625 |
-
abs_offset = data_section_start + ti['offset']
|
| 626 |
-
acc = np.zeros(d0, dtype=np.float64)
|
| 627 |
-
rows_per = max(1, _chunk_max_elems() // max(d0, 1))
|
| 628 |
-
for r0 in range(0, d1, rows_per):
|
| 629 |
-
r1 = min(d1, r0 + rows_per)
|
| 630 |
-
M = _read_src_rows(fin, abs_offset, ttype, d0,
|
| 631 |
-
np.arange(r0, r1, dtype=np.intp))
|
| 632 |
-
acc += M.astype(np.float64, copy=False).sum(axis=0)
|
| 633 |
-
del M
|
| 634 |
-
return acc / max(d1, 1)
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
def _copy_bytes(fin, fout, abs_offset, data_size, chunk=16 * 1024 * 1024):
|
| 638 |
-
fin.seek(abs_offset)
|
| 639 |
-
left = int(data_size)
|
| 640 |
-
while left > 0:
|
| 641 |
-
n = min(left, chunk)
|
| 642 |
-
buf = fin.read(n)
|
| 643 |
-
if not buf:
|
| 644 |
-
raise IOError('short copy from source GGUF')
|
| 645 |
-
fout.write(buf)
|
| 646 |
-
left -= len(buf)
|
| 647 |
-
return int(data_size)
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
def _imat_chunk(ti, imatrix_data, r0, r1, row_perm, col_perm):
|
| 651 |
-
if not imatrix_data:
|
| 652 |
-
return None
|
| 653 |
-
iw = imatrix_data.get(ti['name'])
|
| 654 |
-
if iw is None:
|
| 655 |
-
return None
|
| 656 |
-
iw = np.asarray(iw, dtype=np.float32).reshape(-1)
|
| 657 |
-
d0 = int(ti['dims'][0])
|
| 658 |
-
n_rows = r1 - r0
|
| 659 |
-
n_el = int(ti['n_elements'])
|
| 660 |
-
if iw.size == d0:
|
| 661 |
-
row = iw[col_perm] if col_perm is not None else iw
|
| 662 |
-
return np.ascontiguousarray(np.tile(row, n_rows))
|
| 663 |
-
if iw.size == n_el and ti['n_dims'] >= 2:
|
| 664 |
-
M = iw.reshape(-1, d0)
|
| 665 |
-
rows = row_perm[r0:r1] if row_perm is not None else slice(r0, r1)
|
| 666 |
-
M = M[rows]
|
| 667 |
-
if col_perm is not None:
|
| 668 |
-
M = M[:, col_perm]
|
| 669 |
-
return np.ascontiguousarray(M.reshape(-1))
|
| 670 |
-
return None
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
def _quantize_q4_0_numpy(f32):
|
| 674 |
-
n_el = len(f32)
|
| 675 |
-
if n_el % 32:
|
| 676 |
-
pad = 32 - (n_el % 32)
|
| 677 |
-
f32 = np.concatenate([f32, np.zeros(pad, dtype=np.float32)])
|
| 678 |
-
n_el = len(f32)
|
| 679 |
-
n_blocks = n_el // 32
|
| 680 |
-
blocks = f32.reshape(-1, 32)
|
| 681 |
-
amax = np.max(np.abs(blocks), axis=1)
|
| 682 |
-
d = amax / 7.0
|
| 683 |
-
d[d == 0] = 1.0
|
| 684 |
-
qs = np.clip(np.round(blocks / d[:, None]) + 8, 0, 15).astype(np.uint8)
|
| 685 |
-
d_fp16 = (amax / 7.0).astype(np.float16)
|
| 686 |
-
out_buf = bytearray(n_blocks * 18)
|
| 687 |
-
for b in range(n_blocks):
|
| 688 |
-
off = b * 18
|
| 689 |
-
struct.pack_into('<e', out_buf, off, float(d_fp16[b]))
|
| 690 |
-
for j in range(16):
|
| 691 |
-
out_buf[off + 2 + j] = int(qs[b, j]) | (int(qs[b, j + 16]) << 4)
|
| 692 |
-
return bytes(out_buf), n_blocks
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
def _stream_keep(fin, fout, ti, abs_offset, fb_perms):
|
| 696 |
-
"""Passthrough, optionally applying fold-basis without a full-tensor copy."""
|
| 697 |
-
row_perm, col_perm, is_1d = _fb_axis_maps(ti, fb_perms)
|
| 698 |
-
ttype = ti['type']
|
| 699 |
-
nbytes = _elem_nbytes(ttype)
|
| 700 |
-
if row_perm is None and col_perm is None:
|
| 701 |
-
return _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 702 |
-
if is_1d:
|
| 703 |
-
if nbytes is None:
|
| 704 |
-
return _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 705 |
-
fin.seek(abs_offset)
|
| 706 |
-
raw = fin.read(ti['data_size'])
|
| 707 |
-
f32 = _bytes_to_f32(raw, ttype, ti['n_elements'])
|
| 708 |
-
if f32 is None:
|
| 709 |
-
fout.write(raw)
|
| 710 |
-
return len(raw)
|
| 711 |
-
f32 = f32[row_perm].copy()
|
| 712 |
-
outb = _f32_to_src_bytes(f32, ttype)
|
| 713 |
-
fout.write(outb)
|
| 714 |
-
return len(outb)
|
| 715 |
-
if nbytes is None or ti['n_dims'] < 2:
|
| 716 |
-
return _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 717 |
-
d0 = int(ti['dims'][0])
|
| 718 |
-
d1 = int(ti['dims'][1])
|
| 719 |
-
rows_per = max(1, _chunk_max_elems() // max(d0, 1))
|
| 720 |
-
written = 0
|
| 721 |
-
for r0 in range(0, d1, rows_per):
|
| 722 |
-
r1 = min(d1, r0 + rows_per)
|
| 723 |
-
f32 = _load_dest_chunk_f32(fin, abs_offset, ttype, d0, r0, r1,
|
| 724 |
-
row_perm, col_perm)
|
| 725 |
-
outb = _f32_to_src_bytes(f32, ttype)
|
| 726 |
-
fout.write(outb)
|
| 727 |
-
written += len(outb)
|
| 728 |
-
del f32
|
| 729 |
-
return written
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
def apply_fold_interleave(f32_data, block_size=QK_K):
|
| 733 |
-
"""In-place: k-th smallest at k, k-th largest at k+128.
|
| 734 |
-
Returns uint8 perm: stored[i] = orig[perm[i]]."""
|
| 735 |
-
n = len(f32_data)
|
| 736 |
-
n_blocks = n // block_size
|
| 737 |
-
half = block_size // 2
|
| 738 |
-
all_perms = np.empty(n, dtype=np.uint8)
|
| 739 |
-
x = np.ascontiguousarray(f32_data, dtype=np.float32).reshape(n_blocks, block_size)
|
| 740 |
-
sorted_idx = np.argsort(x, axis=1, kind='mergesort')
|
| 741 |
-
perm = np.empty_like(sorted_idx)
|
| 742 |
-
perm[:, :half] = sorted_idx[:, :half]
|
| 743 |
-
perm[:, half:] = sorted_idx[:, ::-1][:, :half]
|
| 744 |
-
f32_data[:] = np.take_along_axis(x, perm, axis=1).reshape(-1)
|
| 745 |
-
all_perms[:] = perm.astype(np.uint8).reshape(-1)
|
| 746 |
-
return all_perms
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
def apply_fold_interleave_importance(importance, perm_flat, block_size=QK_K):
|
| 750 |
-
n = len(importance)
|
| 751 |
-
n_blocks = n // block_size
|
| 752 |
-
blocks = np.ascontiguousarray(importance, dtype=np.float32).reshape(n_blocks, block_size)
|
| 753 |
-
perms = perm_flat[:n].reshape(n_blocks, block_size).astype(np.intp)
|
| 754 |
-
return np.take_along_axis(blocks, perms, axis=1).reshape(-1)
|
| 755 |
-
|
| 756 |
-
|
| 757 |
-
def _stream_quantize(fin, fout, ti, abs_offset, kind, fb_perms, imatrix_data,
|
| 758 |
-
use_hpc, fold_interleave=False):
|
| 759 |
-
"""Quantize one tensor in row chunks. kind: 'q2k' | 'q4' | 'q8'.
|
| 760 |
-
Returns (n_out_bytes, rmse_or_None). Copies raw if source is already quant.
|
| 761 |
-
"""
|
| 762 |
-
ttype = ti['type']
|
| 763 |
-
if _elem_nbytes(ttype) is None:
|
| 764 |
-
n = _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 765 |
-
return n, None, None
|
| 766 |
-
if ti['n_dims'] < 2 or not ti['dims']:
|
| 767 |
-
n = _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 768 |
-
return n, None, None
|
| 769 |
-
|
| 770 |
-
d0 = int(ti['dims'][0])
|
| 771 |
-
d1 = int(ti['dims'][1])
|
| 772 |
-
row_perm, col_perm, is_1d = _fb_axis_maps(ti, fb_perms)
|
| 773 |
-
if is_1d:
|
| 774 |
-
col_perm = None
|
| 775 |
-
|
| 776 |
-
if kind == 'q2k':
|
| 777 |
-
align = QK_K
|
| 778 |
-
else:
|
| 779 |
-
align = 32
|
| 780 |
-
|
| 781 |
-
if d0 % align != 0:
|
| 782 |
-
raise ValueError(f'{ti["name"]} dim0={d0} not aligned to {align}')
|
| 783 |
-
|
| 784 |
-
rows_per = max(1, _chunk_max_elems() // max(d0, 1))
|
| 785 |
-
total_se = 0.0
|
| 786 |
-
total_ss = 0.0
|
| 787 |
-
total_n = 0
|
| 788 |
-
written = 0
|
| 789 |
-
n_chunks = (d1 + rows_per - 1) // rows_per
|
| 790 |
-
|
| 791 |
-
for r0 in range(0, d1, rows_per):
|
| 792 |
-
r1 = min(d1, r0 + rows_per)
|
| 793 |
-
f32 = _load_dest_chunk_f32(fin, abs_offset, ttype, d0, r0, r1,
|
| 794 |
-
row_perm, col_perm)
|
| 795 |
-
imp = _imat_chunk(ti, imatrix_data, r0, r1, row_perm, col_perm)
|
| 796 |
-
n_valid = int(f32.size)
|
| 797 |
-
total_ss += float(np.vdot(f32, f32))
|
| 798 |
-
total_n += n_valid
|
| 799 |
-
|
| 800 |
-
if kind == 'q2k' and fold_interleave:
|
| 801 |
-
perm_u8 = apply_fold_interleave(f32)
|
| 802 |
-
if imp is not None:
|
| 803 |
-
imp = apply_fold_interleave_importance(imp, perm_u8)
|
| 804 |
-
|
| 805 |
-
if kind == 'q2k':
|
| 806 |
-
if use_hpc:
|
| 807 |
-
qbytes, n_blocks = quantize_tensor_q2k_hpc(
|
| 808 |
-
f32, opt_mode=2, importance=imp, row_width=d0)
|
| 809 |
-
else:
|
| 810 |
-
qbytes, n_blocks = quantize_tensor_q2k(f32)
|
| 811 |
-
fout.write(qbytes)
|
| 812 |
-
written += len(qbytes)
|
| 813 |
-
try:
|
| 814 |
-
deq = dequant_q2k_fast(qbytes, n_blocks)
|
| 815 |
-
n_cmp = min(n_valid, len(deq))
|
| 816 |
-
diff = f32[:n_cmp] - deq[:n_cmp]
|
| 817 |
-
total_se += float(np.sum(diff ** 2))
|
| 818 |
-
except Exception:
|
| 819 |
-
pass
|
| 820 |
-
elif kind == 'q4':
|
| 821 |
-
n_blocks = n_valid // 32
|
| 822 |
-
if (use_hpc and _HEXSTATE_LIB is not None
|
| 823 |
-
and hasattr(_HEXSTATE_LIB, 'hexstate_quantize_tensor_q4_0_hpc')):
|
| 824 |
-
output_buf = np.zeros(n_blocks * 18, dtype=np.uint8)
|
| 825 |
-
error = ctypes.c_float(0.0)
|
| 826 |
-
f32_c = np.ascontiguousarray(f32, dtype=np.float32)
|
| 827 |
-
imat_ptr = None
|
| 828 |
-
if imp is not None:
|
| 829 |
-
imat_ptr = imp.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
| 830 |
-
_HEXSTATE_LIB.hexstate_quantize_tensor_q4_0_hpc(
|
| 831 |
-
f32_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
|
| 832 |
-
ctypes.c_int64(n_valid),
|
| 833 |
-
output_buf.ctypes.data_as(ctypes.c_void_p),
|
| 834 |
-
ctypes.byref(error),
|
| 835 |
-
imat_ptr,
|
| 836 |
-
ctypes.c_int(0),
|
| 837 |
-
)
|
| 838 |
-
qbytes = output_buf.tobytes()
|
| 839 |
-
total_se += float(error.value)
|
| 840 |
-
else:
|
| 841 |
-
qbytes, n_blocks = _quantize_q4_0_numpy(f32)
|
| 842 |
-
fout.write(qbytes)
|
| 843 |
-
written += len(qbytes)
|
| 844 |
-
else:
|
| 845 |
-
n_blocks = n_valid // 32
|
| 846 |
-
if (use_hpc and _HEXSTATE_LIB is not None
|
| 847 |
-
and hasattr(_HEXSTATE_LIB, 'hexstate_quantize_tensor_q8_0_hpc')):
|
| 848 |
-
output_buf = np.zeros(n_blocks * 34, dtype=np.uint8)
|
| 849 |
-
error = ctypes.c_float(0.0)
|
| 850 |
-
f32_c = np.ascontiguousarray(f32, dtype=np.float32)
|
| 851 |
-
imat_ptr = None
|
| 852 |
-
if imp is not None:
|
| 853 |
-
imat_ptr = imp.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
| 854 |
-
_HEXSTATE_LIB.hexstate_quantize_tensor_q8_0_hpc(
|
| 855 |
-
f32_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
|
| 856 |
-
ctypes.c_int64(n_valid),
|
| 857 |
-
output_buf.ctypes.data_as(ctypes.c_void_p),
|
| 858 |
-
ctypes.byref(error),
|
| 859 |
-
imat_ptr,
|
| 860 |
-
ctypes.c_int(0),
|
| 861 |
-
)
|
| 862 |
-
qbytes = output_buf.tobytes()
|
| 863 |
-
total_se += float(error.value)
|
| 864 |
-
else:
|
| 865 |
-
qbytes, n_blocks, sse8 = quantize_tensor_q8_0(f32)
|
| 866 |
-
total_se += float(sse8)
|
| 867 |
-
fout.write(qbytes)
|
| 868 |
-
written += len(qbytes)
|
| 869 |
-
|
| 870 |
-
del f32, imp
|
| 871 |
-
if n_chunks > 1:
|
| 872 |
-
pct = 100.0 * r1 / d1
|
| 873 |
-
print(f"\r β {ti['name'][:40]} {r1}/{d1} rows ({pct:.0f}%)",
|
| 874 |
-
end='', flush=True)
|
| 875 |
-
|
| 876 |
-
if n_chunks > 1:
|
| 877 |
-
print()
|
| 878 |
-
rmse = (np.sqrt(total_se / max(total_n, 1)) if total_n else None)
|
| 879 |
-
sigma = (np.sqrt(total_ss / max(total_n, 1)) if total_n else None)
|
| 880 |
-
return written, rmse, sigma
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
def _fb_prepass(fin, tensor_infos, data_section_start):
|
| 884 |
-
"""P_hidden from first 3 W_q column means; P_inter_N from each W_down."""
|
| 885 |
-
print(" βββ Fold-Basis pre-pass: computing dimension permutations βββ")
|
| 886 |
-
|
| 887 |
-
perms = {}
|
| 888 |
-
hidden_stat = None
|
| 889 |
-
hidden_dim = None
|
| 890 |
-
hidden_count = 0
|
| 891 |
-
|
| 892 |
-
_HIDDEN_SAMPLE = 3
|
| 893 |
-
for ti in tensor_infos:
|
| 894 |
-
if hidden_count >= _HIDDEN_SAMPLE:
|
| 895 |
-
break
|
| 896 |
-
if not (_re.match(r'blk\.\d+\.attn_q\.weight', ti['name']) or
|
| 897 |
-
_re.match(r'blk\.\d+\.attn_qkv\.weight', ti['name'])):
|
| 898 |
-
continue
|
| 899 |
-
if ti['n_dims'] < 2:
|
| 900 |
-
continue
|
| 901 |
-
d0 = int(ti['dims'][0])
|
| 902 |
-
if d0 % QK_K != 0:
|
| 903 |
-
continue
|
| 904 |
-
|
| 905 |
-
col_mean = _stream_col_mean(fin, data_section_start, ti)
|
| 906 |
-
if col_mean is None:
|
| 907 |
-
continue
|
| 908 |
-
|
| 909 |
-
if hidden_stat is None:
|
| 910 |
-
hidden_dim = d0
|
| 911 |
-
hidden_stat = col_mean
|
| 912 |
-
else:
|
| 913 |
-
hidden_stat += col_mean
|
| 914 |
-
hidden_count += 1
|
| 915 |
-
print(f" β P_hidden sample: {ti['name']}")
|
| 916 |
-
|
| 917 |
-
if hidden_stat is not None:
|
| 918 |
-
perms['hidden'] = _fb_compute_perm(hidden_stat)
|
| 919 |
-
print(f" β P_hidden: dim={hidden_dim}, from {hidden_count} Q/QKV tensors")
|
| 920 |
-
|
| 921 |
-
n_inter = 0
|
| 922 |
-
for ti in tensor_infos:
|
| 923 |
-
m = _re.match(r'blk\.(\d+)\.ffn_down\.weight', ti['name'])
|
| 924 |
-
if not m:
|
| 925 |
-
continue
|
| 926 |
-
if ti['n_dims'] < 2:
|
| 927 |
-
continue
|
| 928 |
-
d0 = int(ti['dims'][0])
|
| 929 |
-
if d0 % QK_K != 0:
|
| 930 |
-
continue
|
| 931 |
-
|
| 932 |
-
layer = m.group(1)
|
| 933 |
-
col_mean = _stream_col_mean(fin, data_section_start, ti)
|
| 934 |
-
if col_mean is None:
|
| 935 |
-
continue
|
| 936 |
-
|
| 937 |
-
perms[f'inter_{layer}'] = _fb_compute_perm(col_mean)
|
| 938 |
-
n_inter += 1
|
| 939 |
-
|
| 940 |
-
if n_inter > 0:
|
| 941 |
-
print(f" β P_inter: {n_inter} layers (from W_down column means)")
|
| 942 |
-
|
| 943 |
-
print(f" βββ {len(perms)} permutations computed βββ")
|
| 944 |
-
print()
|
| 945 |
-
return perms
|
| 946 |
-
|
| 947 |
-
|
| 948 |
# βββ Q2_K quantization β faithful port of ggml quantize_row_q2_K_ref βββββββ
|
| 949 |
# Vectorized with numpy for performance. Uses make_qkx2_quants algorithm:
|
| 950 |
# - Weighted MAD error with weights[i] = |x[i]|
|
|
@@ -1272,6 +724,190 @@ def _expand_imatrix(ti, imatrix_data):
|
|
| 1272 |
return np.ascontiguousarray(np.tile(iw, n_el // row_width))
|
| 1273 |
|
| 1274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1275 |
def should_quantize(name, n_dims, dims, tied_embeddings=False):
|
| 1276 |
"""Should this tensor be quantized to Q2_K?
|
| 1277 |
|
|
@@ -1345,9 +981,7 @@ def should_quantize(name, n_dims, dims, tied_embeddings=False):
|
|
| 1345 |
def main():
|
| 1346 |
if len(sys.argv) < 3:
|
| 1347 |
print("Usage: python3 hexstate_requantize.py <input.gguf> <output.gguf>"
|
| 1348 |
-
" [--keep-metadata] [--imatrix FILE] [--keep-embd] [--q2all]"
|
| 1349 |
-
" [--fold-basis] [--no-fold-interleave]")
|
| 1350 |
-
print(" Fold interleave is ON by default (in-block Q2_K layout, no extra tensors).")
|
| 1351 |
print(" HEX_CHUNK_ELEMS max f32 elements per tensor chunk (default 2000000)")
|
| 1352 |
sys.exit(1)
|
| 1353 |
|
|
@@ -1356,9 +990,7 @@ def main():
|
|
| 1356 |
keep_metadata = '--keep-metadata' in sys.argv
|
| 1357 |
quantize_none = '--quantize-none' in sys.argv
|
| 1358 |
q2all = '--q2all' in sys.argv
|
| 1359 |
-
keep_embd = '--keep-embd' in sys.argv
|
| 1360 |
-
fold_basis = '--fold-basis' in sys.argv
|
| 1361 |
-
fold_interleave = '--no-fold-interleave' not in sys.argv
|
| 1362 |
|
| 1363 |
# Check for imatrix
|
| 1364 |
imatrix_data = None
|
|
@@ -1381,17 +1013,13 @@ def main():
|
|
| 1381 |
print(" β GGUF β Q2_K GGUF with metadata passthrough β")
|
| 1382 |
if q2all:
|
| 1383 |
print(" β Mode: --q2all ALL eligible tensors β Q2_K (test mode) β")
|
| 1384 |
-
if fold_interleave:
|
| 1385 |
-
print(" β Fold-interleave: ON (in-block Q2_K, same file size) β")
|
| 1386 |
-
if fold_basis:
|
| 1387 |
-
print(" β Fold-basis: ON (shared dim perm, optional) β")
|
| 1388 |
-
print(f" β Chunk: {_chunk_max_elems():<7d} f32 elems/tensor (HEX_CHUNK_ELEMS) β")
|
| 1389 |
if use_hpc and imatrix_data:
|
| 1390 |
print(" β Engine: HPC + iMatrix (calibrated sensitivity propagation) β")
|
| 1391 |
elif use_hpc:
|
| 1392 |
print(" β Engine: HPC (BP + MSE Grid + Sensitivity Propagation) β")
|
| 1393 |
else:
|
| 1394 |
print(" β Engine: Python (numpy vectorized) β")
|
|
|
|
| 1395 |
print(" ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
|
| 1396 |
print()
|
| 1397 |
|
|
@@ -1452,10 +1080,6 @@ def main():
|
|
| 1452 |
print(f" Data section starts at: {data_section_start:,}")
|
| 1453 |
print()
|
| 1454 |
|
| 1455 |
-
fb_perms = {}
|
| 1456 |
-
if fold_basis:
|
| 1457 |
-
fb_perms = _fb_prepass(fin, tensor_infos, data_section_start)
|
| 1458 |
-
|
| 1459 |
# ββ Detect tied embeddings ββ
|
| 1460 |
# If no separate output.weight tensor exists, token_embd.weight
|
| 1461 |
# doubles as the LM head. Must preserve it at full precision.
|
|
@@ -1677,8 +1301,8 @@ def main():
|
|
| 1677 |
# Header
|
| 1678 |
fout.write(struct.pack('<I', GGUF_MAGIC))
|
| 1679 |
fout.write(struct.pack('<I', GGUF_VERSION))
|
| 1680 |
-
fout.write(struct.pack('<Q',
|
| 1681 |
-
fout.write(struct.pack('<Q',
|
| 1682 |
|
| 1683 |
# KV pairs (passthrough)
|
| 1684 |
for key, vtype, raw_value in updated_kv:
|
|
@@ -1725,45 +1349,39 @@ def main():
|
|
| 1725 |
|
| 1726 |
if plan == 'EMBD_Q8':
|
| 1727 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1728 |
-
fin, fout, ti, abs_offset, 'q8',
|
| 1729 |
-
imatrix_data, use_hpc)
|
| 1730 |
if rmse is not None:
|
| 1731 |
-
print(f"\n [Q8_0Β·Sieve] {ti['name']} RMSE={rmse:.6e}
|
|
|
|
| 1732 |
quant_count += 1
|
| 1733 |
total_quant_bytes += nbytes
|
| 1734 |
|
| 1735 |
elif plan in ('Q4_0', 'Q4_HPC'):
|
| 1736 |
q4_hpc = (plan == 'Q4_HPC' and use_hpc)
|
| 1737 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1738 |
-
fin, fout, ti, abs_offset, 'q4',
|
| 1739 |
-
imatrix_data, q4_hpc)
|
| 1740 |
tag = 'Q4_0Β·HPC' if q4_hpc else 'Q4_0'
|
| 1741 |
if rmse is not None:
|
| 1742 |
-
print(f"\n [{tag}] {ti['name']} RMSE={rmse:.6e}
|
|
|
|
| 1743 |
quant_count += 1
|
| 1744 |
total_quant_bytes += nbytes
|
| 1745 |
|
| 1746 |
elif plan:
|
| 1747 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1748 |
-
fin, fout, ti, abs_offset, 'q2k',
|
| 1749 |
-
imatrix_data, use_hpc,
|
| 1750 |
-
fold_interleave=fold_interleave)
|
| 1751 |
if rmse is not None:
|
| 1752 |
q2k_rmse_sum += rmse
|
| 1753 |
q2k_tensor_count += 1
|
| 1754 |
-
|
| 1755 |
-
|
| 1756 |
else:
|
| 1757 |
print(f"\n [Q2_K] {ti['name'][:55]} RMSE=n/a")
|
| 1758 |
quant_count += 1
|
| 1759 |
total_quant_bytes += nbytes
|
| 1760 |
-
pad = align_offset(fout.tell()) - fout.tell()
|
| 1761 |
-
if pad > 0:
|
| 1762 |
-
fout.write(b'\x00' * pad)
|
| 1763 |
-
continue
|
| 1764 |
|
| 1765 |
else:
|
| 1766 |
-
nbytes =
|
| 1767 |
total_keep_bytes += nbytes
|
| 1768 |
|
| 1769 |
# Alignment padding
|
|
|
|
| 3 |
HexState GGUF Re-Quantizer β GGUF-to-GGUF Q2_K quantization.
|
| 4 |
|
| 5 |
Reads a source GGUF (F16/BF16/F32), copies all metadata verbatim,
|
| 6 |
+
and re-quantizes eligible weight tensors to Q2_K. When
|
| 7 |
+
libhexstate_q2k.so is available, the C HExState optimizer is used for the
|
| 8 |
+
Q2_K/Q4_0/Q8_0 paths; otherwise the numpy fallback is used.
|
|
|
|
|
|
|
| 9 |
|
| 10 |
This bypasses the tokenizer parsing problem entirely β the source GGUF
|
| 11 |
(from llama.cpp's convert_hf_to_gguf.py) has correct metadata.
|
|
|
|
| 20 |
import os
|
| 21 |
import io
|
| 22 |
import ctypes
|
|
|
|
| 23 |
import numpy as np
|
| 24 |
|
| 25 |
# βββ HExState C Library (HPC-optimized Q2_K quantization) ββββββββββββββββββ
|
|
|
|
| 113 |
if hasattr(lib, 'hexstate_set_spectral_params'):
|
| 114 |
lib.hexstate_set_spectral_params.restype = None
|
| 115 |
lib.hexstate_set_spectral_params.argtypes = [
|
| 116 |
+
ctypes.c_float, ctypes.c_float, ctypes.c_float]
|
|
|
|
| 117 |
|
| 118 |
lib.hexstate_init()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
_HEXSTATE_LIB = lib
|
| 120 |
return lib
|
| 121 |
except Exception as e:
|
|
|
|
| 304 |
GGML_TYPE_Q4_0 = 2
|
| 305 |
GGML_TYPE_Q8_0 = 8
|
| 306 |
GGML_TYPE_Q2_K = 10
|
|
|
|
| 307 |
GGML_TYPE_BF16 = 30
|
| 308 |
|
| 309 |
TYPE_NAME = {
|
|
|
|
| 316 |
TYPE_BLOCK_SIZE = {
|
| 317 |
0: 1, 1: 1, 2: 32, 3: 32, 6: 32, 7: 32,
|
| 318 |
8: 32, 9: 32, 10: 256, 11: 256, 12: 256,
|
| 319 |
+
13: 256, 14: 256, 15: 256, 30: 1,
|
| 320 |
}
|
| 321 |
TYPE_BLOCK_BYTES = {
|
| 322 |
0: 4, 1: 2, 2: 18, 3: 20, 6: 20, 7: 22,
|
| 323 |
8: 34, 9: 36, 10: 84, 11: 110, 12: 144,
|
| 324 |
+
13: 176, 14: 210, 15: 292, 30: 2,
|
| 325 |
}
|
| 326 |
|
| 327 |
|
|
|
|
| 397 |
return bf16.tobytes()
|
| 398 |
|
| 399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
# βββ Q2_K quantization β faithful port of ggml quantize_row_q2_K_ref βββββββ
|
| 401 |
# Vectorized with numpy for performance. Uses make_qkx2_quants algorithm:
|
| 402 |
# - Weighted MAD error with weights[i] = |x[i]|
|
|
|
|
| 724 |
return np.ascontiguousarray(np.tile(iw, n_el // row_width))
|
| 725 |
|
| 726 |
|
| 727 |
+
def _chunk_max_elems():
|
| 728 |
+
try:
|
| 729 |
+
return max(QK_K, int(os.environ.get('HEX_CHUNK_ELEMS', '2000000')))
|
| 730 |
+
except ValueError:
|
| 731 |
+
return 2_000_000
|
| 732 |
+
|
| 733 |
+
|
| 734 |
+
def _src_elem_nbytes(ttype):
|
| 735 |
+
if ttype == GGML_TYPE_F32:
|
| 736 |
+
return 4
|
| 737 |
+
if ttype in (GGML_TYPE_F16, GGML_TYPE_BF16):
|
| 738 |
+
return 2
|
| 739 |
+
return None
|
| 740 |
+
|
| 741 |
+
|
| 742 |
+
def _load_rows_f32(fin, abs_offset, ttype, d0, r0, r1):
|
| 743 |
+
n = (r1 - r0) * d0
|
| 744 |
+
es = _src_elem_nbytes(ttype)
|
| 745 |
+
if es is None:
|
| 746 |
+
raise ValueError(f'cannot decode type {ttype} to f32')
|
| 747 |
+
fin.seek(abs_offset + r0 * d0 * es)
|
| 748 |
+
raw = fin.read(n * es)
|
| 749 |
+
if ttype == GGML_TYPE_F32:
|
| 750 |
+
return np.frombuffer(raw, dtype=np.float32).copy()
|
| 751 |
+
if ttype == GGML_TYPE_F16:
|
| 752 |
+
return np.frombuffer(raw, dtype=np.float16).astype(np.float32, copy=False)
|
| 753 |
+
u = np.frombuffer(raw, dtype=np.uint16)
|
| 754 |
+
return (u.astype(np.uint32) << 16).view(np.float32).copy()
|
| 755 |
+
|
| 756 |
+
|
| 757 |
+
def _imat_chunk(ti, imatrix_data, r0, r1, d0):
|
| 758 |
+
if not imatrix_data:
|
| 759 |
+
return None
|
| 760 |
+
iw = imatrix_data.get(ti['name'])
|
| 761 |
+
if iw is None:
|
| 762 |
+
return None
|
| 763 |
+
iw = np.asarray(iw, dtype=np.float32).reshape(-1)
|
| 764 |
+
n_rows = r1 - r0
|
| 765 |
+
if iw.size == int(ti['n_elements']):
|
| 766 |
+
return np.ascontiguousarray(iw[r0 * d0:r1 * d0])
|
| 767 |
+
if iw.size == d0:
|
| 768 |
+
return np.ascontiguousarray(np.tile(iw, n_rows))
|
| 769 |
+
return None
|
| 770 |
+
|
| 771 |
+
|
| 772 |
+
def _copy_bytes(fin, fout, abs_offset, n_bytes):
|
| 773 |
+
fin.seek(abs_offset)
|
| 774 |
+
left = n_bytes
|
| 775 |
+
buf = 16 * 1024 * 1024
|
| 776 |
+
written = 0
|
| 777 |
+
while left > 0:
|
| 778 |
+
chunk = fin.read(min(buf, left))
|
| 779 |
+
if not chunk:
|
| 780 |
+
break
|
| 781 |
+
fout.write(chunk)
|
| 782 |
+
written += len(chunk)
|
| 783 |
+
left -= len(chunk)
|
| 784 |
+
return written
|
| 785 |
+
|
| 786 |
+
|
| 787 |
+
def _stream_quantize(fin, fout, ti, abs_offset, kind, imatrix_data, use_hpc):
|
| 788 |
+
"""Quantize one tensor in row chunks. kind: 'q2k' | 'q4' | 'q8'.
|
| 789 |
+
Returns (n_out_bytes, rmse_or_None, sigma_or_None).
|
| 790 |
+
"""
|
| 791 |
+
ttype = ti['type']
|
| 792 |
+
if _src_elem_nbytes(ttype) is None:
|
| 793 |
+
n = _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 794 |
+
return n, None, None
|
| 795 |
+
if ti['n_dims'] < 2 or not ti['dims']:
|
| 796 |
+
n = _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 797 |
+
return n, None, None
|
| 798 |
+
|
| 799 |
+
d0 = int(ti['dims'][0])
|
| 800 |
+
n_rows = int(ti['n_elements']) // d0
|
| 801 |
+
align = QK_K if kind == 'q2k' else 32
|
| 802 |
+
if d0 % align != 0:
|
| 803 |
+
raise ValueError(f'{ti["name"]} dim0={d0} not aligned to {align}')
|
| 804 |
+
|
| 805 |
+
rows_per = max(1, _chunk_max_elems() // max(d0, 1))
|
| 806 |
+
total_se = 0.0
|
| 807 |
+
total_ss = 0.0
|
| 808 |
+
total_n = 0
|
| 809 |
+
written = 0
|
| 810 |
+
|
| 811 |
+
for r0 in range(0, n_rows, rows_per):
|
| 812 |
+
r1 = min(n_rows, r0 + rows_per)
|
| 813 |
+
f32 = _load_rows_f32(fin, abs_offset, ttype, d0, r0, r1)
|
| 814 |
+
imp = _imat_chunk(ti, imatrix_data, r0, r1, d0)
|
| 815 |
+
n_valid = int(f32.size)
|
| 816 |
+
total_ss += float(np.vdot(f32, f32))
|
| 817 |
+
total_n += n_valid
|
| 818 |
+
|
| 819 |
+
if kind == 'q2k':
|
| 820 |
+
if use_hpc:
|
| 821 |
+
qbytes, n_blocks = quantize_tensor_q2k_hpc(
|
| 822 |
+
f32, opt_mode=2, importance=imp, row_width=d0)
|
| 823 |
+
else:
|
| 824 |
+
qbytes, n_blocks = quantize_tensor_q2k(f32)
|
| 825 |
+
fout.write(qbytes)
|
| 826 |
+
written += len(qbytes)
|
| 827 |
+
try:
|
| 828 |
+
deq = dequant_q2k_fast(qbytes, n_blocks)
|
| 829 |
+
n_cmp = min(n_valid, len(deq))
|
| 830 |
+
diff = f32[:n_cmp] - deq[:n_cmp]
|
| 831 |
+
total_se += float(np.sum(diff ** 2))
|
| 832 |
+
except Exception:
|
| 833 |
+
pass
|
| 834 |
+
del qbytes
|
| 835 |
+
elif kind == 'q4':
|
| 836 |
+
n_el = n_valid
|
| 837 |
+
n_blocks_q4 = n_el // 32
|
| 838 |
+
lib = _load_hexstate_lib() if use_hpc else None
|
| 839 |
+
q4_hpc = lib is not None and hasattr(lib, 'hexstate_quantize_tensor_q4_0_hpc')
|
| 840 |
+
if q4_hpc:
|
| 841 |
+
output_buf = np.zeros(n_blocks_q4 * 18, dtype=np.uint8)
|
| 842 |
+
error = ctypes.c_float(0.0)
|
| 843 |
+
f32_c = np.ascontiguousarray(f32, dtype=np.float32)
|
| 844 |
+
imat_ptr = None
|
| 845 |
+
if imp is not None:
|
| 846 |
+
imat_c = np.ascontiguousarray(imp, dtype=np.float32)
|
| 847 |
+
imat_ptr = imat_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
| 848 |
+
lib.hexstate_quantize_tensor_q4_0_hpc(
|
| 849 |
+
f32_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
|
| 850 |
+
ctypes.c_int64(n_el),
|
| 851 |
+
output_buf.ctypes.data_as(ctypes.c_void_p),
|
| 852 |
+
ctypes.byref(error),
|
| 853 |
+
imat_ptr,
|
| 854 |
+
ctypes.c_int(0),
|
| 855 |
+
)
|
| 856 |
+
fout.write(output_buf.tobytes())
|
| 857 |
+
written += output_buf.size
|
| 858 |
+
total_se += float(error.value)
|
| 859 |
+
del output_buf, f32_c
|
| 860 |
+
else:
|
| 861 |
+
blocks = f32.reshape(-1, 32)
|
| 862 |
+
amax = np.max(np.abs(blocks), axis=1)
|
| 863 |
+
d = amax / 7.0
|
| 864 |
+
d_safe = np.where(d == 0, 1.0, d)
|
| 865 |
+
qs = np.clip(np.round(blocks / d_safe[:, None]) + 8, 0, 15).astype(np.uint8)
|
| 866 |
+
d_fp16 = d.astype(np.float16)
|
| 867 |
+
out_buf = bytearray(n_blocks_q4 * 18)
|
| 868 |
+
for b in range(n_blocks_q4):
|
| 869 |
+
off = b * 18
|
| 870 |
+
struct.pack_into('<e', out_buf, off, float(d_fp16[b]))
|
| 871 |
+
for j in range(16):
|
| 872 |
+
out_buf[off + 2 + j] = int(qs[b, j]) | (int(qs[b, j + 16]) << 4)
|
| 873 |
+
fout.write(bytes(out_buf))
|
| 874 |
+
written += len(out_buf)
|
| 875 |
+
else:
|
| 876 |
+
n_el = n_valid
|
| 877 |
+
n_blocks_q8 = n_el // 32
|
| 878 |
+
lib = _load_hexstate_lib() if use_hpc else None
|
| 879 |
+
if lib is not None and hasattr(lib, 'hexstate_quantize_tensor_q8_0_hpc'):
|
| 880 |
+
output_buf = np.zeros(n_blocks_q8 * 34, dtype=np.uint8)
|
| 881 |
+
error = ctypes.c_float(0.0)
|
| 882 |
+
f32_c = np.ascontiguousarray(f32, dtype=np.float32)
|
| 883 |
+
imat_ptr = None
|
| 884 |
+
if imp is not None:
|
| 885 |
+
imat_c = np.ascontiguousarray(imp, dtype=np.float32)
|
| 886 |
+
imat_ptr = imat_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
| 887 |
+
lib.hexstate_quantize_tensor_q8_0_hpc(
|
| 888 |
+
f32_c.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
|
| 889 |
+
ctypes.c_int64(n_el),
|
| 890 |
+
output_buf.ctypes.data_as(ctypes.c_void_p),
|
| 891 |
+
ctypes.byref(error),
|
| 892 |
+
imat_ptr,
|
| 893 |
+
ctypes.c_int(0),
|
| 894 |
+
)
|
| 895 |
+
fout.write(output_buf.tobytes())
|
| 896 |
+
written += output_buf.size
|
| 897 |
+
total_se += float(error.value)
|
| 898 |
+
del output_buf, f32_c
|
| 899 |
+
else:
|
| 900 |
+
q8_bytes, _, sse8 = quantize_tensor_q8_0(f32)
|
| 901 |
+
fout.write(q8_bytes)
|
| 902 |
+
written += len(q8_bytes)
|
| 903 |
+
total_se += float(sse8)
|
| 904 |
+
del f32
|
| 905 |
+
|
| 906 |
+
rmse = float(np.sqrt(total_se / max(total_n, 1))) if total_n else None
|
| 907 |
+
sigma = float(np.sqrt(total_ss / max(total_n, 1))) if total_n else None
|
| 908 |
+
return written, rmse, sigma
|
| 909 |
+
|
| 910 |
+
|
| 911 |
def should_quantize(name, n_dims, dims, tied_embeddings=False):
|
| 912 |
"""Should this tensor be quantized to Q2_K?
|
| 913 |
|
|
|
|
| 981 |
def main():
|
| 982 |
if len(sys.argv) < 3:
|
| 983 |
print("Usage: python3 hexstate_requantize.py <input.gguf> <output.gguf>"
|
| 984 |
+
" [--keep-metadata] [--imatrix FILE] [--keep-embd] [--q2all]")
|
|
|
|
|
|
|
| 985 |
print(" HEX_CHUNK_ELEMS max f32 elements per tensor chunk (default 2000000)")
|
| 986 |
sys.exit(1)
|
| 987 |
|
|
|
|
| 990 |
keep_metadata = '--keep-metadata' in sys.argv
|
| 991 |
quantize_none = '--quantize-none' in sys.argv
|
| 992 |
q2all = '--q2all' in sys.argv
|
| 993 |
+
keep_embd = '--keep-embd' in sys.argv # keep tied embedding at source precision instead of Q8_0
|
|
|
|
|
|
|
| 994 |
|
| 995 |
# Check for imatrix
|
| 996 |
imatrix_data = None
|
|
|
|
| 1013 |
print(" β GGUF β Q2_K GGUF with metadata passthrough β")
|
| 1014 |
if q2all:
|
| 1015 |
print(" β Mode: --q2all ALL eligible tensors β Q2_K (test mode) β")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1016 |
if use_hpc and imatrix_data:
|
| 1017 |
print(" β Engine: HPC + iMatrix (calibrated sensitivity propagation) β")
|
| 1018 |
elif use_hpc:
|
| 1019 |
print(" β Engine: HPC (BP + MSE Grid + Sensitivity Propagation) β")
|
| 1020 |
else:
|
| 1021 |
print(" β Engine: Python (numpy vectorized) β")
|
| 1022 |
+
print(f" β Chunk: {_chunk_max_elems():<7d} f32 elems/tensor (HEX_CHUNK_ELEMS) β")
|
| 1023 |
print(" ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
|
| 1024 |
print()
|
| 1025 |
|
|
|
|
| 1080 |
print(f" Data section starts at: {data_section_start:,}")
|
| 1081 |
print()
|
| 1082 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1083 |
# ββ Detect tied embeddings ββ
|
| 1084 |
# If no separate output.weight tensor exists, token_embd.weight
|
| 1085 |
# doubles as the LM head. Must preserve it at full precision.
|
|
|
|
| 1301 |
# Header
|
| 1302 |
fout.write(struct.pack('<I', GGUF_MAGIC))
|
| 1303 |
fout.write(struct.pack('<I', GGUF_VERSION))
|
| 1304 |
+
fout.write(struct.pack('<Q', n_tensors))
|
| 1305 |
+
fout.write(struct.pack('<Q', n_kv))
|
| 1306 |
|
| 1307 |
# KV pairs (passthrough)
|
| 1308 |
for key, vtype, raw_value in updated_kv:
|
|
|
|
| 1349 |
|
| 1350 |
if plan == 'EMBD_Q8':
|
| 1351 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1352 |
+
fin, fout, ti, abs_offset, 'q8', imatrix_data, use_hpc)
|
|
|
|
| 1353 |
if rmse is not None:
|
| 1354 |
+
print(f"\n [Q8_0Β·Sieve] {ti['name']} RMSE={rmse:.6e}"
|
| 1355 |
+
f" Ο={sigma:.4f} rel={rmse / max(sigma, 1e-30):.4f}")
|
| 1356 |
quant_count += 1
|
| 1357 |
total_quant_bytes += nbytes
|
| 1358 |
|
| 1359 |
elif plan in ('Q4_0', 'Q4_HPC'):
|
| 1360 |
q4_hpc = (plan == 'Q4_HPC' and use_hpc)
|
| 1361 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1362 |
+
fin, fout, ti, abs_offset, 'q4', imatrix_data, q4_hpc)
|
|
|
|
| 1363 |
tag = 'Q4_0Β·HPC' if q4_hpc else 'Q4_0'
|
| 1364 |
if rmse is not None:
|
| 1365 |
+
print(f"\n [{tag}] {ti['name']} RMSE={rmse:.6e}"
|
| 1366 |
+
f" Ο={sigma:.4f} rel={rmse / max(sigma, 1e-30):.4f}")
|
| 1367 |
quant_count += 1
|
| 1368 |
total_quant_bytes += nbytes
|
| 1369 |
|
| 1370 |
elif plan:
|
| 1371 |
nbytes, rmse, sigma = _stream_quantize(
|
| 1372 |
+
fin, fout, ti, abs_offset, 'q2k', imatrix_data, use_hpc)
|
|
|
|
|
|
|
| 1373 |
if rmse is not None:
|
| 1374 |
q2k_rmse_sum += rmse
|
| 1375 |
q2k_tensor_count += 1
|
| 1376 |
+
print(f"\n [Q2_K] {ti['name'][:50]} RMSE={rmse:.6e}"
|
| 1377 |
+
f" Ο={sigma:.4f} rel={rmse / max(sigma, 1e-30):.4f}")
|
| 1378 |
else:
|
| 1379 |
print(f"\n [Q2_K] {ti['name'][:55]} RMSE=n/a")
|
| 1380 |
quant_count += 1
|
| 1381 |
total_quant_bytes += nbytes
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1382 |
|
| 1383 |
else:
|
| 1384 |
+
nbytes = _copy_bytes(fin, fout, abs_offset, ti['data_size'])
|
| 1385 |
total_keep_bytes += nbytes
|
| 1386 |
|
| 1387 |
# Alignment padding
|