-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathH_inverse_cal.py
More file actions
93 lines (76 loc) · 3.38 KB
/
H_inverse_cal.py
File metadata and controls
93 lines (76 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import os
# Suppress TensorFlow INFO and WARNING messages
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
import keras
import keras.ops as ops
import numpy as np
def get_h_inv_tensorflow(H_numpy):
"""
Calculates H_inv using the pure TensorFlow method, mimicking gptqkeras_fixed.py.
"""
H = tf.convert_to_tensor(H_numpy, dtype=tf.float32)
# Regularize H to ensure it's numerically stable for Cholesky decomposition.
epsilon = 1e-6
H_stable = H + tf.eye(H.shape[0], dtype=H.dtype) * epsilon
try:
L = tf.linalg.cholesky(H_stable)
H_inv = tf.linalg.cholesky_solve(L, tf.eye(H.shape[0], dtype=tf.float32))
return H_inv
except tf.errors.InvalidArgumentError:
print("[TF Fallback] Cholesky failed, using pseudo-inverse.")
return tf.linalg.pinv(H)
def get_h_inv_keras_ops(H_numpy):
"""
Calculates H_inv using the Keras 3.0 ops API.
This version uses ops.linalg.solve, which is the standard Keras 3 way
to solve a system of linear equations and find an inverse.
"""
H = ops.convert_to_tensor(H_numpy, dtype='float32')
# Regularize H for numerical stability.
epsilon = 1e-6
H_stable = H + ops.eye(H.shape[0], dtype=H.dtype) * epsilon
try:
# The standard way to find an inverse is to solve H * X = I for X
I = ops.eye(H.shape[0], dtype='float32')
H_inv = ops.linalg.solve(H_stable, I)
return H_inv
except Exception as e:
# This fallback is unlikely but included for safety.
# We drop to TensorFlow for pinv as it's not in keras.ops
print(f"[Keras Fallback] Solve failed ({e}), using TF pseudo-inverse.")
H_tf = tf.convert_to_tensor(H_numpy, dtype=tf.float32)
H_inv_tf = tf.linalg.pinv(H_tf)
return ops.convert_to_tensor(H_inv_tf.numpy())
def main():
"""
Main function to run the comparison test.
"""
print("--- H_inv Calculation Comparison: TensorFlow vs. Keras 3.0 ---")
# 1. Create a sample positive semi-definite matrix (like a real Hessian)
matrix_size = 128
np.random.seed(0)
# Create a random matrix A, then compute A.T * A to ensure it's positive semi-definite
A = np.random.rand(matrix_size, matrix_size).astype(np.float32)
H_numpy = np.dot(A.T, A)
print(f"\nGenerated a {matrix_size}x{matrix_size} positive semi-definite matrix H.")
# 2. Calculate H_inv using both methods
h_inv_tf = get_h_inv_tensorflow(H_numpy)
h_inv_keras = get_h_inv_keras_ops(H_numpy)
# 3. Calculate the scalar sum of all elements in each result
sum_tf = tf.reduce_sum(h_inv_tf).numpy()
sum_keras = ops.sum(h_inv_keras).numpy() # Use .numpy() to extract scalar
# 4. Print results and the difference
print("\n--- Results ---")
print(f"Sum of H_inv elements (TensorFlow): {sum_tf}")
print(f"Sum of H_inv elements (Keras ops): {sum_keras}")
difference = abs(sum_tf - sum_keras)
print(f"\nAbsolute Difference: {difference}")
if difference > 1e-5:
print("\nConclusion: The results are DIFFERENT.")
print("This confirms that the underlying implementations produce numerically different outputs,")
print("which will lead to cumulative error in iterative algorithms like GPTQ.")
else:
print("\nConclusion: The results are effectively the same.")
if __name__ == "__main__":
main()