As noted by glennsl in comments, per the manual the type variables (e.g. 'a) are defined for the entire toplevel definition where they occur.
In general the scope of a named type variable is the whole top-level phrase where it appears
Consider defining a simple function f with a locally scoped function g which specifies a type of 'a -> 'a:
# let f x y =
let g (x : 'a) : 'a = x in
(g x, g y);;
val f : 'a -> 'a -> 'a * 'a = <fun>
Because 'a is scoped to the definition of f it has to be unified accordingly. The only way this can work is if x and y have the same type.
There is no such restriction if we elide the explicit type annotation on g.
# let f x y =
let g x = x in
(g x, g y);;
val f : 'a -> 'b -> 'a * 'b = <fun>
Another example. Starting without explicit type annotations. The compiler correctly infers that all four arguments must have wildcard types. It uses 'a through 'd'.
# let f a b c d =
let g x y = (x, y) in
let h x y = (x, y) in
(g a b, h c d);;
val f : 'a -> 'b -> 'c -> 'd -> ('a * 'b) * ('c * 'd) = <fun>
And adding the explicit type annotation, the compiler infers that all four arguments must have wildcard types, but because we have already via passing them as arguments to g and h given those types names, a and c mst both save the same type, as must b and d.
# let f a b c d =
let g (x : 'a) (y : 'b) : ('a * 'b) = (x, y) in
let h (x : 'a) (y : 'b) : ('a * 'b) = (x, y) in
(g a b, h c d);;
val f : 'a -> 'b -> 'a -> 'b -> ('a * 'b) * ('a * 'b) = <fun>