Ok, so it looks like the iptables rules were correct for the nth and packet parameters. There's conflicting information about how to set it up, with some people incrementing the value of --packet, and others incrementing the value of --every. Regardless, the hit counts match, and that's the important part.
That said, it looks like anything on ports 80 and 443 and 8443 are NOT balanced, and that's likely where the discrepancy was coming from.
Code:
[1] -A PREROUTING -i br0 -m state --state NEW -j balance
[2] -A balance -d 192.168.0.1/24 -j RETURN
[3] -A balance -d 10.x.x.x/32 -j RETURN
[4] -A balance -d 10.x.x.x/32 -j RETURN
[5] -A balance -p tcp -m tcp --dport 443 -j RETURN
[6] -A balance -p tcp -m tcp --dport 8443 -j RETURN
[7] -A balance -p udp -m udp --dport 443 -j RETURN
[8] -A balance -p udp -m udp --dport 80 -j RETURN
[9] -A balance -m connmark --mark 0x80000000/0x80000000 -j RETURN
[10] -A balance -m state --state RELATED,ESTABLISHED -j RETURN
[11] -A balance -m statistic --mode nth --every 2 --packet 0 \
-j CONNMARK --set-xmark 0x80000000/0xf0000000
[12] -A balance -m statistic --mode nth --every 2 --packet 1 \
-j CONNMARK --set-xmark 0x90000000/0xf0000000
I removed rules 4 (dupe), 5, 6, 7, and 8.
I also added a final rule "-j RETURN" just to get a total count of the CONNMARKed packets with iptables -vL.
Finally, I also checked the marks in /proc/net/ip_conntrack before and after making changes. Before the change, they were ~2:1 in favor of 0x80000000 (ppp0) vs 0x90000000 (ppp1). Now they're roughly the same.
If anyone knows a good reason to keep rules 5, 6, 7, and 8, please let me know.