1. 개요
MatMul은 두 텐서의 마지막 두 축을 행렬로 해석하여 행렬 곱을 수행한다.
두 입력을 다음과 같이 두자.
A.shape = (..., m, k)
B.shape = (..., k, n)
출력은 다음 shape를 가진다.
C = A @ B
C.shape = (..., m, n)
앞쪽의 batch 축은 broadcasting 규칙에 따라 결합된다.
수학적으로는 다음과 같다.
Cᵢⱼ = Σₚ Aᵢₚ Bₚⱼ
MatMul의 핵심 의미는 다음과 같다.
- 두 피연산자 전체에 대해서는 선형이 아니라 쌍선형이다.
- 한쪽 피연산자를 고정하면 다른 쪽에 대해서는 선형이다.
- 두 입력 전체는 출력만으로 복원할 수 없다.
- 한쪽 입력이 알려져 있어도 항상 복원 가능한 것은 아니다.
- 복원 가능성은 고정된 행렬의 rank와 shape에 의해 결정된다.
- 출력의 rank는 내부 차원과 두 피연산자의 rank에 의해 제한된다.
- 출력 feature 수가 증가해도 독립적인 정보 차원이 증가하는 것은 아니다.
2. 입력 및 출력 규칙
2.1 입력 개수
MatMul은 정확히 두 개의 입력을 요구한다.
MatMul(A, B)
2.2 dtype 규칙
두 입력은 동일한 dtype을 가져야 한다.
A.dtype == B.dtype
현재 구현은 암묵적인 dtype promotion을 허용하지 않는다.
float32 @ float64 → 오류
int32 @ float32 → 오류
이 정책은 정적 타입 추론과 실제 실행 결과를 일치시키기 위한 것이다.
2.3 rank 규칙
현재 구현은 rank가 2 이상인 텐서만 허용한다.
A.ndim >= 2
B.ndim >= 2
NumPy의 matmul은 1차원 벡터에 대한 특별 규칙도 제공하지만, 현재 연산자에서는 이를 의도적으로 제외한다.
따라서 모든 입력은 마지막 두 차원을 명시적인 행렬 차원으로 가진다.
2.4 내부 차원 규칙
행렬 곱을 수행하려면 다음 두 차원이 같아야 한다.
A.shape[-1] == B.shape[-2]
즉,
A: (..., m, k)
B: (..., k, n)
이어야 한다.
k는 두 입력 사이에서 합산되는 내부 차원이다.
2.5 batch broadcasting
마지막 두 행렬 차원을 제외한 앞쪽 차원은 broadcasting될 수 있다.
예를 들어 다음 연산은 유효하다.
(4, 3) @ (3, 8) → (4, 8)
(10, 4, 3) @ (3, 8) → (10, 4, 8)
(1, 4, 3) @ (7, 3, 8) → (7, 4, 8)
(5, 1, 4, 3) @ (1, 6, 3, 8) → (5, 6, 4, 8)
batch 차원이 broadcasting될 수 없다면 연산은 유효하지 않다.
3. 대수적 성질
3.1 결합 입력 전체에 대해서는 선형이 아님
MatMul을 두 입력 전체에 대한 함수로 정의한다.
F(A, B) = AB
선형 함수라면 다음이 성립해야 한다.
F(tA, tB) = tF(A, B)
하지만 실제로는 다음과 같다.
F(tA, tB)
= (tA)(tB)
= t²AB
일반적으로 다음은 성립하지 않는다.
t²AB = tAB
따라서 MatMul은 결합 입력 (A, B) 전체에 대해서는 선형이 아니다.
"linear": False
3.2 쌍선형성
MatMul은 한쪽 피연산자를 고정하면 다른 쪽에 대해 선형이다.
B를 고정하면:
F_B(A) = AB
다음이 성립한다.
(aA₁ + bA₂)B
= aA₁B + bA₂B
따라서 A에 대해 선형이다.
반대로 A를 고정하면:
F_A(B) = AB
다음이 성립한다.
A(aB₁ + bB₂)
= aAB₁ + bAB₂
따라서 B에 대해서도 선형이다.
이처럼 각각의 피연산자에 대해서는 선형이지만, 두 피연산자를 동시에 변수로 보면 선형이 아닌 연산을 쌍선형이라고 한다.
algebraic kind: bilinear
권장 semantic fact는 다음과 같다.
SemanticFact(
"algebraic_kind",
"bilinear",
EvidenceLevel.GUARANTEED,
)
3.3 nonlinear=True의 의미
현재 분석 결과에는 다음이 포함되어 있다.
"linear": False,
"nonlinear": True,
결합 입력 전체에 대한 함수라는 기준에서는 맞다.
(A, B) → AB
는 선형 함수가 아니기 때문이다.
그러나 신경망 문맥에서는 MatMul을 일반적으로 선형 연산으로 부르기도 한다.
예를 들어 가중치 W가 고정되어 있을 때:
Y = XW
는 입력 X에 대한 선형 변환이다.
따라서 다음 두 의미를 구분해야 한다.
두 입력을 모두 변수로 봄:
(A, B) → AB는 bilinear이며 jointly nonlinear
가중치 B를 고정함:
A → AB는 linear
현재의 nonlinear=True가 ReLU, Sigmoid와 같은 활성화 비선형성과 동일하게 집계되면 분석 결과가 혼동될 수 있다.
예를 들어 다음 그래프를 생각할 수 있다.
X → MatMul(X, W) → MatMul(_, V)
W와 V가 고정된 파라미터라면 전체 데이터 변환은 여전히 선형이다.
(XW)V = X(WV)
그런데 각각의 MatMul을 단순히 nonlinear=True로 집계하면 이 그래프에 비선형 연산이 두 개 있다고 잘못 해석할 수 있다.
따라서 다음과 같이 성질을 분리하는 것이 좋다.
"jointly_linear": False,
"linear_in_each_operand": True,
"activation_nonlinear": False,
"algebraic_kind": "bilinear",
기존 필드를 유지한다면 nonlinear의 정의를 다음처럼 명시해야 한다.
모든 명시적 입력을 동시에 변수로 간주했을 때 선형이 아닌가?
4. 동차성
MatMul은 각 피연산자에 대해 1차 동차이다.
(tA)B = t(AB)
A(tB) = t(AB)
하지만 두 피연산자를 동시에 같은 값으로 스케일하면 2차로 변한다.
(tA)(tB) = t²AB
따라서 결합 입력에 대해서는 2차 동차 연산으로 볼 수 있다.
homogeneous degree with joint scaling: 2
이 성질은 MatMul이 단순한 선형 병합이 아니라 두 입력 사이의 곱셈적 상호작용을 생성한다는 것을 보여준다.
5. 파라미터 개수
"parameter_count": 0
이 정의는 적절하다.
MatMul 연산자 자체는 학습 가능한 파라미터를 소유하지 않는다.
MatMul(A, B)
에서 B가 학습 가능한 가중치 텐서일 수는 있지만, 그 파라미터는 MatMul 연산자가 아니라 입력 텐서 또는 별도의 Parameter 객체가 소유한다.
따라서 다음을 구분해야 한다.
연산자 자체의 파라미터 수:
0
입력으로 전달된 파라미터 텐서의 원소 수:
별도 그래프 분석 대상으로 계산
6. 출력 rank 제한
단일 batch에 대해 다음 행렬 곱을 생각한다.
A ∈ R^(m×k)
B ∈ R^(k×n)
C = AB ∈ R^(m×n)
정확한 선형대수에서는 다음이 성립한다.
rank(AB) ≤ min(rank(A), rank(B))
또한:
rank(A) ≤ min(m, k)
rank(B) ≤ min(k, n)
따라서:
rank(AB) ≤ min(m, k, n)
현재 코드의 upper bound는 이를 shape만으로 표현한다.
min(
left.shape[-2],
left.shape[-1],
right.shape[-1],
)
즉:
min(m, k, n)
이다.
6.1 shape 기반 upper bound
이 값은 실제 입력값을 보지 않고 shape만으로 얻을 수 있는 최대 rank이다.
보다 명확한 이름은 다음과 같다.
shape_based_rank_upper_bound
또는:
algebraic_rank_upper_bound
실제 rank는 이보다 작을 수 있다.
예를 들어:
A의 행들이 서로 선형 종속
B의 열들이 서로 선형 종속
A 또는 B가 영행렬
이라면 출력 rank는 더 낮아진다.
6.2 부동소수점 실행에서의 주의
다음 관계는 정확한 산술에서 성립한다.
rank(AB) ≤ min(rank(A), rank(B))
하지만 실제 부동소수점 MatMul 결과는 정확한 AB가 아니라 반올림된 근삿값이다.
fl(AB) = AB + E
여기서 E는 수치 오차이다.
반올림 오차는 이론적인 저랭크 구조를 미세하게 깨뜨릴 수 있다.
따라서 min(m, k, n)을 내부 차원에 의한 대수적 rank 병목으로 해석하려면 이상적인 정확한 산술을 전제로 하는 것이 더 엄밀하다.
권장 표현은 다음과 같다.
SemanticFact(
"algebraic_rank_upper_bound",
min(m, k, n),
EvidenceLevel.IDEALIZED,
"Exact matrix multiplication satisfies rank(AB) <= min(m, k, n).",
)
IDEALIZED를 사용하지 않는다면 다음과 같이 분리할 수 있다.
출력 shape에 의한 rank 제한:
rank(C) ≤ min(m, n)
내부 차원 k에 의한 factorization 병목:
정확한 산술에서 rank(C) ≤ k
첫 번째는 출력 행렬 shape 자체에서 나오는 제한이고, 두 번째는 행렬 곱의 대수적 구조에서 나오는 제한이다.
7. 차원 변화
현재 구현은 다음 값으로 차원 효과를 판단한다.
right.shape[-1] < left.shape[-1]
이를 기호로 표현하면 다음과 같다.
입력 feature 차원: k
출력 feature 차원: n
즉, A의 각 행을 하나의 feature vector로 해석하고 B를 변환 행렬로 해석한다.
x ∈ R^k
xB ∈ R^n
따라서:
n < k → compression
n = k → preservation
n > k → expansion
이라고 분류할 수 있다.
7.1 이 분류는 shape 변화만 의미함
dimension_effect="expansion"은 정보나 표현력이 반드시 증가한다는 의미가 아니다.
예를 들어:
B ∈ R^(k×n), n > k
이면 출력 vector는 n개의 좌표를 가지지만, 가능한 출력이 차지하는 독립적인 차원은 최대 k이다.
rank(B) ≤ k
즉, 더 넓은 공간으로 이동했을 뿐 새로운 독립 정보를 생성한 것은 아니다.
R^k → R^n, n > k
는 injective embedding이 될 수 있지만, 입력보다 더 많은 독립 자유도를 생성하지는 않는다.
따라서 expansion은 다음 의미로 해석해야 한다.
출력 좌표 또는 feature width가 증가한다.
다음 의미로 해석해서는 안 된다.
입력 정보의 독립 차원이나 표현력이 자동으로 증가한다.
7.2 compression
n < k
이면 B는 최대 rank가 n이다.
rank(B) ≤ n < k
따라서 A의 각 행에 대한 변환:
x → xB
은 injective일 수 없다.
서로 다른 입력 vector가 같은 출력 vector를 만들 수밖에 없다.
즉, feature 차원 축소는 구조적으로 정보 손실을 발생시킨다.
n < k
→ unavoidable dimensional collapse
7.3 preservation
n = k
는 입력과 출력 feature 수가 같다는 뜻이다.
하지만 이것만으로 정보가 보존된다고 결론 내릴 수는 없다.
B가 singular하다면:
rank(B) < k
이고 일부 입력 방향이 제거된다.
정보가 보존되려면 B가 full rank여야 한다.
정사각행렬인 경우:
det(B) ≠ 0
이어야 한다.
따라서 preservation은 정확히는 다음 의미이다.
feature width preservation
이지:
information preservation
이 아니다.
7.4 expansion
n > k
이면 출력 feature 수가 증가한다.
이 경우 B가 full row rank를 가지면 입력 vector를 출력으로부터 복원할 수 있다.
rank(B) = k
그러나 B가 rank deficient라면 출력 폭이 증가해도 정보 손실이 발생한다.
따라서 expansion은 다음 두 경우로 나뉜다.
full row rank:
복원 가능한 embedding
rank deficient:
넓은 공간으로 표현되지만 일부 입력 방향은 붕괴
8. 결합 입력의 비가역성
MatMul은 출력만으로 두 입력을 동시에 복원할 수 없다.
C = AB
라는 결과만 주어졌을 때 A와 B의 분해는 일반적으로 유일하지 않다.
임의의 invertible matrix S ∈ R^(k×k)에 대해:
AB = (AS)(S⁻¹B)
가 성립한다.
즉, 서로 다른 입력 쌍:
(A, B)
(AS, S⁻¹B)
가 동일한 출력을 만든다.
이는 단순한 우연이 아니라 내부 표현 기저를 변경할 수 있기 때문에 발생하는 구조적인 모호성이다.
따라서:
SemanticFact(
"joint_input_recoverable",
False,
EvidenceLevel.GUARANTEED,
"Matrix factorization is generally non-unique.",
)
는 적절하다.
보다 구체적인 설명은 다음과 같다.
The output does not uniquely determine both operands because
AB = (AS)(S^-1B) for any compatible invertible matrix S.
9. 다대일 성질
결합 입력 전체에 대해 MatMul은 다대일 함수이다.
(A, B) → AB
여러 입력 쌍이 동일한 결과를 만들 수 있다.
가장 단순한 예는 스케일링 모호성이다.
AB = (tA)(B/t)
단, t ≠ 0이다.
따라서 다음 semantic fact를 추가할 수 있다.
SemanticFact(
"many_to_one",
True,
EvidenceLevel.GUARANTEED,
"Distinct matrix-factor pairs can produce the same product.",
)
10. 다른 피연산자가 알려진 경우의 복원
MatMul은 Add와 달리 다른 한쪽 피연산자가 알려져 있다고 해서 항상 나머지를 복원할 수 있는 것은 아니다.
복원 가능성은 알려진 행렬의 rank에 따라 달라진다.
10.1 B가 알려진 경우 A 복원
다음을 생각한다.
C = AB
A ∈ R^(m×k)
B ∈ R^(k×n)
C ∈ R^(m×n)
B와 C가 주어진 상태에서 A를 복원하려면 다음 변환이 injective여야 한다.
A → AB
각 행 vector 관점에서는:
x → xB
이다.
이 변환이 injective이려면 B가 full row rank여야 한다.
rank(B) = k
이는 다음 조건을 필요로 한다.
n ≥ k
B가 full row rank라면 right inverse R이 존재한다.
BR = I_k
따라서:
A = CR
로 복원할 수 있다.
반대로:
rank(B) < k
이면 B의 left null direction에 해당하는 입력 성분이 사라지므로 A를 유일하게 복원할 수 없다.
10.2 A가 알려진 경우 B 복원
A와 C가 알려져 있을 때 B를 복원하려면 다음 변환이 injective여야 한다.
B → AB
이를 위해서는 A가 full column rank여야 한다.
rank(A) = k
이는 다음 조건을 필요로 한다.
m ≥ k
A가 full column rank라면 left inverse L이 존재한다.
LA = I_k
따라서:
B = LC
로 복원할 수 있다.
10.3 정사각 가역행렬
가장 단순한 경우는 정사각 가역행렬이다.
B가 invertible이면:
A = CB⁻¹
A가 invertible이면:
B = A⁻¹C
그러나 일반적인 직사각 행렬에서는 inverse 대신 full-rank 조건과 left 또는 right inverse가 필요하다.
10.4 권장 semantic facts
다음과 같이 복원 가능성을 양쪽 피연산자에 대해 분리하는 것이 좋다.
SemanticFact(
"left_recoverable_given_right",
"conditional",
EvidenceLevel.GUARANTEED,
"A is uniquely recoverable from AB and B when B has full row rank.",
),
SemanticFact(
"right_recoverable_given_left",
"conditional",
EvidenceLevel.GUARANTEED,
"B is uniquely recoverable from A and AB when A has full column rank.",
),
다만 fact의 값에 문자열 "conditional"을 사용하는 것보다는 증거 수준에 CONDITIONAL을 추가하는 편이 더 일관적이다.
SemanticFact(
"left_recoverable_given_right",
True,
EvidenceLevel.CONDITIONAL,
"Requires the right operand to have full row rank.",
)
SemanticFact(
"right_recoverable_given_left",
True,
EvidenceLevel.CONDITIONAL,
"Requires the left operand to have full column rank.",
)
11. broadcasting과 복원성
batch broadcasting이 적용되면 동일한 피연산자가 여러 batch에서 재사용될 수 있다.
예를 들어:
A.shape = (batch, m, k)
B.shape = (k, n)
이면 동일한 B가 모든 batch에 적용된다.
C_b = A_b B
각 batch의 A_b를 복원하려면 여전히 B가 full row rank여야 한다.
반대로 B가 미지수이고 여러 A_b와 C_b가 주어진다면, 여러 batch의 정보를 결합해 B를 추정할 수 있다.
A₁B = C₁
A₂B = C₂
...
각각의 A_b가 full column rank가 아니더라도, 이들을 세로로 쌓은 행렬이 full column rank라면 B를 유일하게 결정할 수 있다.
stack(A₁, A₂, ...)의 rank = k
따라서 broadcasting이 있는 전체 그래프 수준의 복원 가능성은 단일 행렬 곱보다 더 복잡할 수 있다.
연산자 수준에서는 일반적인 per-batch 조건만 기록하고, 공유 operand를 이용한 전역 복원 가능성은 그래프 분석 단계에서 다루는 것이 적절하다.
12. 붕괴 관점에서의 해석
MatMul은 단순히 shape를 바꾸는 연산이 아니라 입력 공간의 방향들을 선택, 혼합 또는 제거한다.
고정된 B에 대해:
x → xB
를 생각할 수 있다.
B의 null space에 속하는 방향 v가 존재하면:
vB = 0
이다.
따라서 다음 두 입력은 동일한 출력을 만든다.
(x + v)B = xB + vB = xB
즉, B의 null space 방향에 존재하던 입력 차이는 출력에서 완전히 사라진다.
이것이 MatMul에서 발생하는 핵심적인 붕괴이다.
collapse directions = null space of B
12.1 차원 축소와 필연적 붕괴
B ∈ R^(k×n)
에서:
n < k
이면 rank-nullity theorem에 따라:
dim(null(B)) = k - rank(B)
이고:
rank(B) ≤ n
이므로:
dim(null(B)) ≥ k - n > 0
이다.
따라서 최소한 k-n개의 독립적인 입력 방향이 반드시 소실된다.
n < k
→ nontrivial null space is unavoidable
→ collapse is guaranteed
12.2 차원 유지와 붕괴 가능성
n = k
라도 B가 singular하면 null space가 존재한다.
rank(B) < k
따라서 shape가 유지되어도 정보 붕괴가 발생할 수 있다.
12.3 차원 확장과 정보 보존
n > k
일 때 B가 full row rank이면 null space가 없다.
rank(B) = k
dim(null(B)) = 0
이 경우 입력은 더 높은 차원의 출력 공간에 injective하게 매핑된다.
하지만 출력은 n차원 공간 전체를 자유롭게 사용하는 것이 아니라 최대 k차원의 부분공간에 놓인다.
따라서 이는 새로운 정보를 생성하는 확장이 아니라 다음과 같이 해석할 수 있다.
information-preserving embedding into a wider coordinate space
13. 표현력 관점
고정된 행렬 B를 사용하는 MatMul은 입력 feature를 새로운 선형 조합으로 변환한다.
y_j = Σᵢ x_i B_ij
각 출력 feature는 입력 feature들의 가중합이다.
따라서 MatMul은:
- 기존 feature를 혼합할 수 있다.
- 새로운 좌표계를 만들 수 있다.
- 특정 방향을 강조하거나 제거할 수 있다.
- 차원을 줄이거나 늘릴 수 있다.
- 비선형적인 결정 경계를 직접 만들지는 못한다.
고정된 MatMul을 여러 번 연속 적용해도 전체는 하나의 MatMul로 합칠 수 있다.
(XW₁)W₂ = X(W₁W₂)
따라서 중간에 비선형 연산이 없다면 깊이가 증가해도 함수 계열 자체의 선형 표현력은 증가하지 않는다.
다만 중간 차원에 의해 rank 제한이 생길 수 있다.
X → XW₁ → XW₁W₂
에서 중간 feature 수가 r이라면:
rank(W₁W₂) ≤ r
이다.
따라서 연속 MatMul은 하나의 MatMul로 합칠 수 있지만, 중간 차원이 최종 변환의 최대 rank를 제한할 수 있다.
이 성질은 linear chain fusion의 의미적 기반이 된다.
14. 결합법칙과 compiler rewrite
정확한 행렬대수에서는 행렬 곱의 결합법칙이 성립한다.
(AB)C = A(BC)
따라서 세 개 이상의 연속 MatMul은 다른 순서로 계산해도 수학적인 결과가 같다.
하지만 계산 비용은 크게 달라질 수 있다.
예를 들어:
A: m×k
B: k×r
C: r×n
일 때:
(AB)C 비용:
mkr + mrn
A(BC) 비용:
krn + mkn
shape에 따라 더 저렴한 순서가 달라진다.
따라서 compiler는 matrix-chain multiplication 최적화를 적용할 수 있다.
14.1 부동소수점에서는 bitwise 동일하지 않음
실제 부동소수점에서는 연산 순서가 달라지면 반올림 위치도 달라진다.
따라서 일반적으로:
fl(fl(AB)C) ≠ fl(A fl(BC))
일 수 있다.
수학적으로는 동등하지만 bitwise 동일성이 보장되지는 않는다.
따라서 다음을 구분해야 한다.
algebraically associative:
True
bitwise reassociation safe:
False
approximately equivalent under tolerance:
일반적으로 가능하지만 수치 조건에 의존
compiler rewrite를 위해 다음 semantic fact가 유용하다.
SemanticFact(
"associative",
True,
EvidenceLevel.IDEALIZED,
"Matrix multiplication is associative in exact arithmetic.",
),
SemanticFact(
"bitwise_reassociation_safe",
False,
EvidenceLevel.GUARANTEED,
"Floating-point reassociation can change rounding behavior.",
),
14.2 분배법칙
정확한 산술에서는 다음도 성립한다.
A(B + C) = AB + AC
(A + B)C = AC + BC
이 성질은 fusion, factorization 및 common-subexpression optimization에 활용할 수 있다.
하지만 부동소수점에서는 역시 bitwise 동일성을 보장하지 않는다.
15. 파생 가능한 compiler 최적화
MatMul의 의미 정의로부터 다음 rewrite를 고려할 수 있다.
연속 MatMul 결합
(XA)B → X(AB)
전제 조건:
- shape 호환
- 파라미터 또는 상수 행렬을 미리 곱할 수 있음
- 파라미터 증가 및 감소 분석
- 부동소수점 reassociation 정책 허용
- 학습 시 gradient 및 파라미터 의미 보존 여부 확인
identity 제거
XI → X
IX → X
정확한 identity가 보장되는 경우 적용할 수 있다.
zero 전파
X0 → 0
0X → 0
다만 NaN 및 Inf를 엄격하게 고려하면 IEEE 부동소수점에서는 주의가 필요하다.
예를 들어:
Inf × 0 → NaN
이 가능하므로 입력값에 대한 finite 조건 없이 단순한 zero rewrite는 항상 안전하지 않다.
transpose rewrite
(AB)ᵀ = BᵀAᵀ
이는 layout 및 kernel 선택 최적화에 활용할 수 있다.
rank-aware fusion
연속 MatMul을 합쳤을 때 중간 rank bottleneck이 최종 weight에 반영될 수 있다.
W_fused = W₁W₂
이때:
rank(W_fused) ≤ intermediate_width
이다.
compiler는 이 성질을 사용해 단순한 shape 기반 fusion을 넘어 저랭크 구조까지 분석할 수 있다.
16. 현재 분석 정의의 평가
현재 정의는 다음과 같다.
return {
"op_type": self.op_type,
"parameter_count": 0,
"linear": False,
"nonlinear": True,
"irreversible": True,
"rank_upper_bound": min(
left.shape[-2],
left.shape[-1],
right.shape[-1],
),
"dimension_effect": (
"compression"
if right.shape[-1] < left.shape[-1]
else "expansion"
if right.shape[-1] > left.shape[-1]
else "preservation"
),
}
각 항목은 다음과 같이 평가할 수 있다.
| parameter_count=0 | 적절함 | operand가 parameter일 수 있다는 점은 별도 분석 |
| linear=False | 결합 입력 기준으로 적절함 | 데이터 입력 기준 선형성과 구분 필요 |
| nonlinear=True | 결합 입력 기준으로 적절함 | activation nonlinearity와 분리 필요 |
| irreversible=True | 결합 입력 기준으로 적절함 | 한쪽 operand가 주어진 조건부 복원성 추가 |
| rank_upper_bound | 정확한 선형대수에서 적절함 | algebraic 또는 shape-based라는 이름 권장 |
| dimension_effect | feature width 변화로 적절함 | 정보 보존 또는 실제 rank 변화로 해석하면 안 됨 |
항목평가보완점
17. 권장 분석 정의
현재 구조를 크게 바꾸지 않는다면 다음처럼 보완할 수 있다.
def analyze(
self,
inputs: list[TensorSpec],
output: TensorSpec,
) -> AnalysisDict:
left, right = inputs
m = left.shape[-2]
k = left.shape[-1]
n = right.shape[-1]
return {
"op_type": self.op_type,
"parameter_count": 0,
# Joint map: (A, B) -> AB
"linear": False,
"nonlinear": True,
"algebraic_kind": "bilinear",
# Distinguish bilinear interaction from activation nonlinearity.
"jointly_linear": False,
"linear_in_each_operand": True,
"activation_nonlinear": False,
"irreversible": True,
"joint_input_recoverable": False,
"shape_based_rank_upper_bound": min(m, k, n),
# Width change of left operand's final feature axis.
"feature_dimension_effect": (
"compression"
if n < k
else "expansion"
if n > k
else "preservation"
),
"input_feature_dim": k,
"output_feature_dim": n,
"contracted_dim": k,
}
핵심은 nonlinear=True만으로 MatMul의 성질을 표현하지 않고, bilinear interaction이라는 사실을 별도로 기록하는 것이다.
18. 권장 semantic facts
def semantic_facts(
self,
inputs: list[TensorSpec],
output: TensorSpec,
) -> tuple[SemanticFact, ...]:
left, right = inputs
m = left.shape[-2]
k = left.shape[-1]
n = right.shape[-1]
return (
SemanticFact(
"algebraic_kind",
"bilinear",
EvidenceLevel.GUARANTEED,
"Matrix multiplication is bilinear in its two operands.",
),
SemanticFact(
"jointly_linear",
False,
EvidenceLevel.GUARANTEED,
"Scaling both operands scales the output quadratically.",
),
SemanticFact(
"linear_in_each_operand",
True,
EvidenceLevel.GUARANTEED,
"The map is linear in either operand when the other is fixed.",
),
SemanticFact(
"activation_nonlinear",
False,
EvidenceLevel.GUARANTEED,
"Bilinearity is distinct from elementwise activation nonlinearity.",
),
SemanticFact(
"many_to_one",
True,
EvidenceLevel.GUARANTEED,
"Distinct matrix-factor pairs can produce the same product.",
),
SemanticFact(
"joint_input_recoverable",
False,
EvidenceLevel.GUARANTEED,
"The factorization is generally non-unique.",
),
SemanticFact(
"left_recoverable_given_right",
True,
EvidenceLevel.CONDITIONAL,
"Requires the right operand to have full row rank.",
),
SemanticFact(
"right_recoverable_given_left",
True,
EvidenceLevel.CONDITIONAL,
"Requires the left operand to have full column rank.",
),
SemanticFact(
"algebraic_rank_upper_bound",
min(m, k, n),
EvidenceLevel.IDEALIZED,
"Exact multiplication satisfies rank(AB) <= min(m, k, n).",
),
SemanticFact(
"feature_dimension_effect",
(
"compression"
if n < k
else "expansion"
if n > k
else "preservation"
),
EvidenceLevel.GUARANTEED,
"Describes feature width only, not information preservation.",
),
SemanticFact(
"associative",
True,
EvidenceLevel.IDEALIZED,
"Matrix multiplication is associative in exact arithmetic.",
),
SemanticFact(
"bitwise_reassociation_safe",
False,
EvidenceLevel.GUARANTEED,
"Floating-point reassociation can change rounding results.",
),
)
19. EvidenceLevel이 아직 확장되지 않은 경우
현재 EvidenceLevel에 CONDITIONAL이나 IDEALIZED가 없다면 다음처럼 단계적으로 적용할 수 있다.
SemanticFact(
"left_recoverable_given_right_full_row_rank",
True,
EvidenceLevel.GUARANTEED,
"If the right operand has full row rank, the left operand is recoverable.",
)
조건 자체를 fact 이름에 포함하면 GUARANTEED를 유지할 수 있다.
마찬가지로 rank upper bound도 다음처럼 표현할 수 있다.
SemanticFact(
"exact_arithmetic_rank_upper_bound",
min(m, k, n),
EvidenceLevel.GUARANTEED,
"Under exact arithmetic, rank(AB) cannot exceed this value.",
)
즉, 증거 수준을 확장하지 않더라도 fact가 성립하는 전제를 이름과 설명에 명시하면 된다.
20. 최종 의미 요약
MatMul은 두 입력 행렬 사이의 곱셈적 상호작용을 생성하는 쌍선형 연산이다.
(A, B) → AB
두 피연산자를 동시에 변수로 보면 선형이 아니지만, 한쪽을 고정하면 다른 쪽에 대해서는 선형이다.
출력만으로 두 입력 행렬을 동시에 복원할 수는 없다. 이는 행렬 분해가 일반적으로 유일하지 않기 때문이다.
AB = (AS)(S⁻¹B)
다른 한쪽 피연산자가 알려진 경우에도 복원은 자동으로 보장되지 않는다.
A 복원:
B가 full row rank여야 함
B 복원:
A가 full column rank여야 함
출력 feature 수의 증가는 좌표 수의 증가일 뿐, 새로운 독립 정보를 생성한다는 의미가 아니다.
MatMul에서 실제 정보 붕괴를 결정하는 핵심은 단순한 출력 shape가 아니라 고정된 변환 행렬의 rank와 null space이다.
대수적 종류:
bilinear
결합 입력에 대한 선형성:
False
각 피연산자에 대한 선형성:
True
활성화 비선형성:
False
결합 입력 복원:
불가능
한쪽 입력이 주어진 경우:
상대 행렬의 full-rank 조건에서만 가능
rank 병목:
rank(AB) ≤ min(rank(A), rank(B))
정확한 산술에서 rank(AB) ≤ min(m, k, n)
붕괴의 원인:
변환 행렬의 null space와 rank deficiency
dimension expansion:
feature width 증가일 뿐 독립 정보 증가가 아님
compiler 관점:
연속 MatMul 결합, 행렬 곱 순서 최적화,
rank-aware fusion 및 reassociation 분석 가능
'AI Compiler framework' 카테고리의 다른 글
| 낮은 Effective Rank 란 무엇인가 (0) | 2026.07.06 |
|---|---|
| Linear 연산 합성 실험 결과 분석 (0) | 2026.07.06 |
| Add 연산자 의미 정의 (1) | 2026.07.05 |
| AI Compiler 프로젝트 개발 재시작 방향 (0) | 2026.07.05 |
| AICF / MCIR 에서 패턴의 새로운 정의 (0) | 2026.03.23 |