scikit-learn SVC with custom precomputed kernel matrix uses too much memory I need to implement a custom kernel for the sklearn.svm.SVC learner.
My custom kernel consists in multiplying every element of the kernel matrix except the main diagonal by a fixed constant (the "correction" factor). According to scikit-learn docs I can use a standard SVC with parameter kernel='precomputed' and fit by passing the Gram matrix and the target variable.
Adapting from their example (copied from the link above):
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn import svm
X, y = make_classification(n_samples=130000, random_state=42)
X_train , X_test , y_train, y_test = train_test_split(X, y, random_state=42)
clf = svm.SVC(kernel='precomputed')
# custom kernel computation
mu = 0.25
sigma_squared = mu * (1.0 - mu)
correction = 1.0 - 4 * sigma_squared
linear_gm = np.dot(X_train, X_train.T)
diag_values = np.diag(linear_gm)
corrected_gram_matrix = linear_gm * correction
np.fill_diagonal(corrected_gram_matrix, diag_values)

clf.fit(corrected_gram_matrix, y_train)

# predict on training examples
gram_test = np.dot(X_test, X_train.T)
clf.predict(gram_test)

The problem is that precomputing the Gram matrix in this way takes up too much memory and the Google Colab instance I am using crashes with the following:
tcmalloc: large alloc 76050006016 bytes

That's about 76GB of RAM, so running on my computer is not an option either.
Removing my correction part and just changing the number of samples in their example produces the same result. What's worse is that this number (130000) is a toy example, as the actual dataset I will use has nearly 1 million samples and 120 features.
I know the other possible way to use a custom kernel is to define a function and pass the callable as the kernel parameter in the SVC constructor, but the function needs to have the signature f(X, Y) and would operate on one sample at a time without knowing if the kernel value is on the diagonal or not, which would in turn make my correction impossible.
Is there any other (or better, feasible) way  to implement my custom kernel?

By definition the diagonal is the case where you're evaluating $f(x,x)$ - thus, you should provide your own function $f(x,y)$:
unscaled = k(x,y)
return x == y ? unscaled : scalingFactor * unscaled

Note that this calculation is correct in that if you have multiple identical points, the kernel definition should not be dependent on the fact that it's the same index in the matrix, but rather the values of the operands.
