PCA and SVD for low-rank matrices, LOBPCG for positive-defined generalized eigenvalue problem#29488
PCA and SVD for low-rank matrices, LOBPCG for positive-defined generalized eigenvalue problem#29488pearu wants to merge 41 commits intopytorch:masterfrom
Conversation
|
LOBPCG Algorithm 1 from Duersch et al, 2018 appears to simply be the original Algorithm 5.1 from A. V. Knyazev, Toward the Optimal Preconditioned Eigensolver: Locally Optimal Block Preconditioned Conjugate Gradient Method. SIAM Journal on Scientific Computing 23 (2001), no. 2, pp. 517-541. http://dx.doi.org/10.1137/S1064827500366124 It is probably appropriate the cite the original paper... Also, this implementation may become unstable for various reasons. |
|
@lobpcg Thanks for your comment! With the current sparse test matrices, the basic lobpcg works ok. While there are several (large) sparse matrices available for which the basic lobpcg might have problems, using these in pytorch test-site might be unfeasible due to their size. So, I wonder if you could provide any hints for how to generate relatively small sparse matrices where the basic lobpcg is guaranteed to fail? |
|
It is not a matter of being sparse or dense, or even large/small. The instability mostly appears when the vectors in the RR become linearly dependent for any reason, unless one runs expensive explicit full orthogonalization prior to RR. Easy ways to break RR:
And there are few trickier ones, with special choices of the initial guesses. It is difficult, but still possible to break the latest code |
|
@pytorchbot rebase this please |
💊 CircleCI build failures summary and remediationsAs of commit 76c3cfb (more details on the Dr. CI page): Commit 76c3cfb was recently pushed. Waiting for builds... This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.Please report bugs/suggestions on the GitHub issue tracker. This comment has been revised 81 times. |
65abdb7 to
0717e11
Compare
|
The PR is ready for review. |
|
This PR implementations of LOBPCG do not follow Not a blocker, but may want to keep this in mind if there would be a need in the future to improve performance for large block sizes. Thanks for your implementations! |
|
I'm working on finding some good reviewers for this PR. |
|
@vincentqb has graciously accepted to review this PR. @nikitaved, if you also want to bill Quansight time to help review this PR, that would also be fine by me. |
|
@lobpcg How does this diff look to you? Happy to assign you as a reviewer too. |
|
@ezyang I support this PR, but unfamiliar with pytorch. And this PR code is rather long, so I am unable to formally review, but thanks for asking. I've looked briefly at a couple of core functions, and not noticed anything troubling, just had a comment #29488 (comment) |
|
@pearu it may also help reviewers quite a bit if we split this PR into one per piece of functionality, if this is easily possible (I haven't read it yet so I don't know if there's some dependence) |
|
Indeed, this PR implements two new features, low-rank SVD and LOBPCG, which are independent methods. However, the expected expertise of reviewers is the same and both features depend on some new utility methods needed for testing (see tests/common_utils.py), and some minor fixes in torch/_six.py and torch/serialization.py. |
|
That's cool. In that case the utility of splitting would mostly be being able to land one part earlier than the rest, but if we're not in a rush let's just keep it together. |
vincentqb
left a comment
There was a problem hiding this comment.
Thanks for working on this. I've done a first pass on SVD/PCA.
b7c3b41 to
e36ccec
Compare
|
Thanks @vincentqb for the review of the SVD/PCA part. I have addressed all your questions and concerns. There is an open question of whether we should keep the complex input support or not because the pytorch complex support is incomplete currently. |
55a362f to
f5385d7
Compare
Let's remove the annotation for now. We can open a separate pull request to make this jitable, and discuss why decorating doesn't work. |
|
@vincentqb I believe my last commit fixes the issue: the decorator is removed and lobpcg is torchscript jit'able. |
|
Phabricator is refusing to update the original internal diff. We'll need to open a new PR to land the change. I'll close this one in the meanwhile. @pearu -- can you push the change to a new PR, and link to this one? I'll approve it and merge it from there. |
|
@vincentqb done creating a new PR. |
|
@pearu - Amazing work, thanks a lot! |
@nikitaved @lobpcg -- Are you interested in writing about this? :) |
|
@vincentqb , absolutely! |
|
Great! I'm adding @wookim3 to the loop. |
|
this is really cool, thanks for working on this!! |
|
I do not think I can write it, never running pytorch myself, but I would be glad to review/edit. Please feel free to ping me. |
|
@nikitaved - Thank you! To get started, can you share your email address? We can create a Google doc and collaborate together on there. cc @vincentqb |
|
@wookim3, sure, [email protected] it is. Thank you! But just so it is clear, it is a tutorial we are talking about, right? |
This PR implements the following linear algebra algorithms for low-rank matrices:
AasQ Q^H A- using Algorithm 4.4 from Halko et al, 2009.torch.lowrank.get_approximate_basis(A, q, niter=2, M=None) -> Qtorch.lowrank.get_approximate_basistorch.svd_lowrank(A, q=6, niter=2, M=None) -> (U, S, V)torch.svd_lowranktorch.svd_lowranktorch.pca_lowrank(A, center=True, q=None, niter=2) -> (U, S, V)torch.lobpcg(A, B=None, k=1, method="basic", ...)torch.lobpcg(A, B=None, k=1, method="ortho", ...)trackerargument allows breaking the iteration process at user choice so that the user can switch to the orthogonal basis selection if needed. In conclusion, there is no need to implement Algorithm 8 at this point.torch.svdvstorch.svd_lowrank, see notebook Low-rank SVD. In conclusion, the low-rank SVD is going to be useful only for large sparse matrices where the full-rank SVD will fail due to memory limitations.torch.lobpcgvsscipy.sparse.linalg.lobpcg, see notebook LOBPCG - pytorch vs scipy. In conculsion, both implementations give the same results (up to numerical errors from different methods), scipy lobpcg implementation is generally faster.torch.lobpcgis more robust thanscipy.sparse.linalg.lobpcg(seetest_lobpcg_scipyresults)Resolves #8049.